The main goal of this set of rules is to establish healthy boundaries where cleaner code will be easier to share, more scalable, more readable and easier to maintain for everyone.
These linting rules comes preconfigured as a precommit hook. This means it will not allow you nor anyone in your project to commit to the repository if any of these rules are invalid. Although it might look restrictive at the beginning offers many advantages later on as commented above.
In order to do so we decided to rely on Eslint, a great Javascript linter by Nicholas C. Zakas and SCSS-Lint for... yes! SASS linting.
If you are wondering if this set of rules if for you here's a brief description. Keep reading to get a detailed description.
####SASS Linting won't let you:
- Add color values directly to a property. You must use variables instead.
- Set short #hex values.
- Use of
!important
- ...
####in SASS linting you must:
- Merge rules of same selector.
- Set properties to
0
instead ofnone
. - Match the selector format to the Naming Convention
- ...
-
- BangFormat
- BorderZero
- ColorVariable
- Comment
- DebugStatement
- DeclarationOrder
- DuplicateProperty
- ElsePlacement
- EmptyLineBetweenBlocks
- EmptyRule
- FinalNewline
- HexLength
- HexNotation
- HexValidation
- IdSelector
- ImportantRule
- ImportPath
- Indentation
- LeadingZero
- MergeableSelector
- NameFormat
- NestingDepth
- PlaceholderInExtend
- PropertySortOrder
- PropertySpelling
- SelectorDepth
- SelectorFormat
- Shorthand
- SingleLinePerProperty
- SingleLinePerSelector
- SpaceAfterComma
- SpaceAfterPropertyColon
- SpaceAfterPropertyName
- SpaceBeforeBrace
- SpaceBetweenParens
- StringQuotes
- TrailingSemicolon
- TrailingZero
- UnnecessaryMantissa
- UnnecessaryParentReference
- UrlFormat
- UrlQuotes
- VendorPrefixes
- ZeroUnit
This documentation is a step by step guide to add JS, SASS and React linter in Sublime Text 3. Feel free to use the code editor of your choice. Just make sure you can add Eslint and SCSS-Lint config files.
- Make sure you have Package Control installed in your copy of Sublime Text by pressing
cmd + Shift + p
and typingPackage Control: Install Package
. - If doesn't show up check out this page and install it first: packagecontrol.io.
- Open Package Control and install:
SublimeLinter
Sublime Linter Plugin. Important Note: This plugin is no longer including linting files so you need to install them apart.
SASS and SCSS-Lint are Ruby Gems. You need to meet the following requeriments:
- Ruby 1.9.3+ Installed: Check out Ruby install page.
- Sass 3.4.1+ Installed: Check out SASS install page.
- Files you wish to lint must be written in SCSS (not SASS) syntax.
- Open Package control by typing:
cmd + shift + p
and then search forinstall package
- Select
SublimeLinter-contrib-sass-lint
- Reopen Sublime Text if necessary.
- SASS linting rules must be defined in a
.scss-lint.yml
file in the root directory.
- Install the Eslint CLI from a global node package by typing
npm i -g eslint
in your terminal. - Open Package control by typing:
cmd + shift + p
and then search forinstall package
- Select
SublimeLinter-contrib-eslint
- Reopen Sublime Text if necessary
- Javascript linting rules must be defined in a
.eslintrc
file in the root directory.
Here you'll find a use case example for every SASS linting rule specified in this set:
Defines the right use of the bang !
in !default
, !global
, and !optional
flags.
Bad
$c-bg-light: #ffffff!default
Good
$c-bg-light: #ffffff !default
Set properties to border: 0
over border: none
.
Bad
border: none;
Good
border: 0;
To avoid colour entropy all arround the site is mandatory to set colour using SASS variables as shown in the example below. Colour parametrization ensures better maintainability and are more verbose than setting an hex value as #bada55
Bad: literal color
.sui-Card-title {
color: green;
}
Good: refer to color by variable name
$body-color: #c0ffee;
...
.sui-Card-title {
color: $body-color;
}
Althoug comments are enabled consider using //
comments over /* ... */
. The former are more precise single line comments while the later tends to be multiple lines comments rendered in the final css file.
Bad
/* This is a multi line
comment that gets rendered
and tends to be too generic */
Good
// This is a one line concise non rendered comment
@debug
statements are not allowed.
Place @extend
and @include
before properties so you can overwrite them later if needed.
Bad
.sui-Card-mediaContent {
p {
...
}
color: #bg-light;
@extend %sui-Card-boxContent;
@include message-box();
}
Good
.sui-Card-mediaContent {
@extend %sui-Card-boxContent;
@include message-box();
color: #bg-light;
p {
...
}
}
Usually, if you set the same property twice inside the same selector is a mistake so you're not allowed to do so:
Bad
.sui-Card {
float: left;
text-transform: uppercase;
float: right; // Second declaration
}
Place @else
statements on the same line as the preceding curly brace.
Bad
@if {
...
}
@else {
...
}
Good
@if {
...
} @else {
...
}
Ad extra separation line between every declaration block. In nested declarations is also mandatory.
Bad: no lines separating blocks
.sui-Component {
margin: 0;
.sui-Subcomponent {
...
}
}
a {
...
}
Good: Use an empty separation line
.sui-Component {
margin: 0;
.sui-Subcomponent {
...
}
}
a {
...
}
One line declarations doesn't apply.
.sui-Icon { &:before { content: "\e030"; } }
To avoid useless empty declarations in your code, this rule reports when you have an empty rule set:
.sui-Card {
}
Insert an empty final line of code in every file. This is helpful for better Git diffs.
Set always hexadecimal color values in long format
Bad: no long format hex value
$c-bg-light: #fe0:
.sui-Component {
background-color: $c-bg-light;
}
Good: Long format hex value applied to a SASS var
$c-bg-light: #bada55:
.sui-Component {
background-color: $c-bg-light;
}
Reports uppercase hex color notation:
Bad: Uppercase notation is not allowed
$c-bg-light: #BADA55:
.sui-Component {
background-color: $c-bg-light;
}
Good: Lowercase hex notation value applied to a SASS var
$c-bg-light: #bada55:
.sui-Component {
background-color: $c-bg-light;
}
Ensure hexadecimal colors are valid
Bad: Hexadecimal color values must be 6 digits long, lowercase and only if contains these characters: 0123456789abcdef
$c-bg-light: #bazh5:
.sui-Component {
background-color: $c-bg-light;
}
Good: Valid hex value applied to a SASS var
$c-bg-light: #bada55:
.sui-Component {
background-color: $c-bg-light;
}
To avoid highly specific selectors ID's are not allowed to apply SASS styling:
Bad: ID selector
#sui-Component {
background-color: $c-bg-light;
}
Good: Apply Class selector instead
.sui-Component {
background-color: $c-bg-light;
}
In order to avoid specificity problems using !important
in SASS properties is not allowed.
Bad:
.sui-Component {
background-color: $c-bg-light !important;
}
Good: Apply Class selector instead
.sui-Component {
background-color: $c-bg-light;
}
An imported partials SASS file paths cannot have preceding underscores _
but it must contain a .scss
expension declared in path in order to be compatible with the node-sass v.3.4.1
.
This update to node-sass
is mandatory to execute this package under Node v.4.
Bad
@import "foo/_bar.scss";
@import "_bar.scss";
@import "_bar";
@import "bar.scss";
Good
@import "foo/bar";
@import "bar";
Default basic indentation is set to the followind value:
- Indentation 2 spaces.
In the other hand, automatic indentation can be performed by Editorconfig to ensure a consistent coding style no matter what editor or IDE you use. Consists of a hidden file named .editorconfig
and a plugin that needs to be installed in your code editor.
Also helps Github diffing tool to avoid incorrect file changes. The presets included in Editorconfig are:
[*]
- Applies the following rules to all characters in files.indent_style = space
- Use soft tabs for indentation.indent_size = 2
- 2 columns are used for each indentation.end_of_line = lf
- Line ending are set to line feedcharset = utf-8
- Character encoding is set to utf-8.trim_trailing_whitespace = true
- Whitespace preceding new lines is removed.insert_final_newline = true
- An empty new line at the end of every file must to be added.
Markdown files has the following rule redefined:
indent_size = 4
- 4 columns are used for each indentation.
Make sure you install the right plugin for your code editor. Check out the EditorConfig website to get the right one.
If you are using Sublime Text:
- open Package Control.
- Type
EditorConfig
. - Press
enter
to Install it.
Don't write leading zeros for numeric values with a decimal point.
Bad: unnecessary leading zero
margin: 0.5em;
Good: no leading zero
margin: .5em;
Reports when you define the same selector twice in a single sheet.
Bad
h1 {
margin: 10px;
}
.baz {
color: red;
}
// Second copy of h1 rule
h1 {
text-transform: uppercase;
}
Functions, mixins, variables, and placeholders should be declared with all lowercase letters and hyphens instead of underscores.
Bad: uppercase characters
$myVar: 10px;
@mixin myMixin() {
...
}
Good: all lowercase with hyphens
$my-var: 10px;
@mixin my-mixin() {
...
}
The max nesting selectors in SASS files is: 4 levels.
Bad: descendent name anidation add overspecificity
.sui-Component {
…
&-header {
…
}
&-avatar {
…
}
&-bodyText {
…
}
}
Good: each descendent name is not anided with the parent
.sui-Component {
…
}
.sui-Component-header {
…
}
.sui-Component-avatar {
…
}
.sui-Component-bodyText {
…
}
Always use placeholder selectors in @extend
to avoid generating more code than necessary.
Bad: extending a class
.fatal {
@extend .error;
}
Good: extending a placeholder
.fatal {
@extend %error;
}
Use alphabetical order in your declaration statements. If you are using Sublime Text select all the properties and press F5
to automatic sorting. Note: No grouping or line spaces between property blocks are allowed.
Bad: No alphabetically ordered properties
.sui-Component {
width: 100%;
background-color: $c-bg-light;
margin: 0 auto;
}
Good: Alphabetically ordered properties
.sui-Component {
background-color: $c-bg-light;
margin: 0 auto;
width: 100%;
}
Reports when you use an unknown CSS property (ignoring vendor-prefixed properties).
diplay: none; // "display" is spelled incorrectly
Max depth of selectors applicability is set to 3.
Bad: selectors with depths of 4
.one .two .three > .four {
...
}
.one .two {
.three > .four {
...
}
}
Good: Max depth of 3
.one .two .three {
...
}
.one .two {
.three {
...
}
}
The selector format naming convention used here is based in SUIT CSS
It must match the following RegEx:
^(?:[a-zA-Z0-9]*)\-[A-Z]{1}[a-z][a-zA-Z0-9]*(?:\-[a-z][a-zA-Z0-9]*)?(?:\-\-[a-z][a-zA-Z0-9]*)?$
Perhaps you prefer to see an example:
.pre-MyComponent {}
.pre-MyComponent.is-animating {}
.pre-MyComponent--modifier {}
.pre-MyComponent-element {}
.pre-MyComponent-anotherElement {}
Shortest shorthand for properties that support it are mandatory.
Bad: all 4 sides specified with same value
margin: 1px 1px 1px 1px;
Good: equivalent to specifying 1px for all sides
margin: 1px;
Properties within rule sets should each reside on their own line.
Bad
p {
margin: 0; padding: 0;
}
Good
p {
margin: 0;
padding: 0;
}
Split selectors onto separate lines after each comma, and have each individual selector occupy a single line.
Bad: comma-separated selectors not on their own lines
.error p, p.explanation {
...
}
Bad: descendent selector spread over multiple lines
.error
p,
p.explanation {
...
}
Good: each selector sequence is on its own individual line
.error p,
p.explanation {
...
}
Commas in lists should be followed by a space.
Bad: no space after commas
@include box-shadow(0 2px 2px rgba(0,0,0,.2));
color: rgba(0,0,0,.1);
Good: commas followed by a space
@include box-shadow(0 2px 2px rgba(0, 0, 0, .2));
color: rgba(0, 0, 0, .1);
Properties should be formatted with a single space separating the colon from the property's value.
Bad: no space after colon
margin:0;
Bad: more than one space after colon
margin: 0;
Good: Just a single space after colon
margin: 0;
Properties should be formatted with no space between the name and the colon.
Bad: space before colon
margin : 0;
Good
margin: 0;
Opening braces should be preceded by a single space.
Bad: no space before brace
.sui-Button{
...
}
Bad: more than one space before brace
.sui-Button {
...
}
Good
.sui-Button {
...
}
For Single Line Blocks extra spaces are allowed to better align code:
.sui-Arrow--up { &:before { content: "\e030"; } }
.sui-Arrow--down { &:before { content: "\e031"; } }
.sui-Arrow--left { &:before { content: "\e032"; } }
.sui-Arrow--right { &:before { content: "\e033"; } }
Parentheses should not be padded with spaces.
Bad
@include box-shadow( 0 2px 2px rgba( 0, 0, 0, .2 ) );
color: rgba( 0, 0, 0, .1 );
Good
@include box-shadow(0 2px 2px rgba(0, 0, 0, .2));
color: rgba(0, 0, 0, .1);
String literals should be written with single quotes unless using double quotes would save on escape characters.
The reason why we prefer single quotes is because are easier to type (no shift key needed) in most keyboards.
Bad: double quotes
content: "hello";
Good: single quotes
content: 'hello';
Good: double quotes prevent the need for escaping single quotes
content: "'hello'";
All property values including; @extend
, @include
, and @import
directives; and variable declarations should always end with a semicolon.
Although in CSS you can omit the semicolon if the statement is the last one it might lead to inconsistencies.
Bad: no semicolon
p {
color: #fff
}
Bad: space between value and semicolon
p {
color: #fff ;
}
Good
p {
color: #fff;
}
Don't write trailing zeros for numeric values with a decimal point in order to save additional bytes in generated CSS files.
Bad: unnecessary trailing zero
margin: .500em;
padding: 0.5em
Good: no trailing zero
margin: .5em;
padding: .5em
Numeric values should not contain unnecessary fractional portions. Otherwhise SASS will take that value as an unnecesary floating point unit reducing performance and increasing memory usage.
Bad
margin: 1.0em;
Good
margin: 1em;
Do not use parent selector references (&
) when they would otherwise be
unnecessary.
Bad
.sui-Card {
& > .sui-Card-content {
...
}
}
Good
.sui-Card {
> .sui-Card-content {
}
}
URLs should not contain protocols or domain names.
Including protocols or domains in URLs makes them brittle to change, and also unnecessarily increases the size of your CSS documents, reducing performance.
Bad: protocol and domain present
background: url('https://example.com/assets/image.png');
Good
background: url('assets/image.png');
In order to be consistent with other SASS asset helpers URLs should always be enclosed within quotes.
Bad: no enclosing quotes
background: url(example.png);
Good
background: url('example.png');
Avoid vendor prefixes. Use autoprefixer
tools. Don't write them yourself.
Bad: vendor prefixes
@-webkit-keyframes anim {
0% { opacity: 0; }
}
Good
// Autoprefix later in pre/post SASS processing...
@keyframes anim {
0% { opacity: 0; }
}
Because zero is zero regardless of the units of length, omit length units on zero values.
Bad: unnecessary units
margin: 0px;
Good
margin: 0;