This is a living document and new ideas are always welcome.
- BangFormat
- BorderZero
- ColorKeyword
- ColorVariable
- Comment
- DeclarationOrder
- ElsePlacement
- IdSelector
- ImportPath
- Indentation
- LeadingZero
- NameFormat
- NestingDepth
- PlaceholderInExtend
Well commented code is extremely important.
Begin every section block with a title.
// *************************************
//
// #SECTION-TITLE
//
// *************************************
.selector {}
Each title should be preceded by five (5) carriage returns.
// *************************************
//
// #SECTION-ALPHA
//
// *************************************
.selector-alpha {}
// *************************************
//
// #SECTION-BETA
//
// *************************************
.selector-beta {}
Begin every sub-section block with a title.
// #SUB-SECTION-TITLE
// *************************************
.selector {}
Consistency is key.
There are other reasons for shorter lines, apart from history and screen sizes:
- Viewing code side by side (diffs, merges, etc).
- Viewing code in other media (Github, email, etc).
- Catching refactoring opportunities.
- Code readability (human eye can't scan long horizontal lines fast).
// Now, while it's still good practice to keep code below 80 columns, this
// isn't one of those rules that needs to be followed religiously, contorting
// yourself to make some line fit when it just doesn't. I suggest that you try
// to keep all of your code under 80 columns, but when it just doesn't fit,
// don't worry about it too much.
IDs, classes, types, placeholders, and pseudo-selectors should be all lowercase.
// bad
.Selector {}
// good
.selector {}
Rule sets should be ordered as follows: @extend
declarations, @include
declarations, then nested rule sets.
// bad
.selector {
padding: 10px;
@include box();
@extend %clearfix;
}
// good
.selector {
@extend %clearfix;
@include box();
padding: 10px;
}
Don't write leading zeros for numeric values with a decimal point.
// bad: unnecessary leading zero
.selector {
padding: 0.75em;
}
// good: no leading zero
.selector {
padding: .75em;
}
URLs should always be enclosed within quotes.
Using quoted URLs is consistent with using other Sass asset helpers, which also expect quoted strings. It also works better with most syntax highlighters, and makes it easier to escape characters, as the escape rules for strings apply, rather than the different set of rules for literal URLs.
// bad: no enclosing quotes
.selector {
background: url(example.png);
}
// good
.selector {
background: url("example.png");
}
Below is a list of linters supported by scss-lint, ordered alphabetically.
Reports when you use improper spacing around !
(the "bang") in !important
and !default
declarations.
// bad
$color-brand: #222!default;
// good
$color-brand: #222 !default;
Prefer the terser border: 0
over border: none
.
// bad
.selector {
border: none;
}
// good
.selector {
border: 0;
}
Prefer hexadecimal color codes over color keywords.
// bad: color keyword
$color-brand: black;
// good: hexadecimal color
$color-brand: #222;
Prefer color literals (keywords or hexadecimal codes) to be used only in variable declarations. They should be referred to via variables everywhere else.
// bad: literal color
a {
color: blue;
}
// good: refer to color by variable name
$color-base-links: #0a81ae;
a {
color: $color-base-links
}
Prefer //
comments over /* ... */
.
// bad
/* This is a comment that gets rendered. */
// good
// This comment never gets rendered.
Rule sets should be ordered as follows: @extend
declarations, @include
declarations without inner @content
, properties, @include
declarations
with inner @content
, then nested rule sets.
// bad
.selector {
.selector__item {
...
}
font-size: 20px;
@extend %clearfix;
@include box;
}
// good
.selector {
@extend %clearfix;
@include box;
font-size: 20px;
.selector__item {
...
}
}
Place @else
statements on the same line as the preceding curly brace.
// bad
@if {
...
}
@else {
...
}
// good
@if {
...
} @else {
...
}
Avoid using ID selectors.
// bad: highly-specific styling for a single element via ID
#selector {}
// good: reusable class
.selector {}
The basenames of @import
ed SCSS partials should not begin with an underscore
and should not include the filename extension.
// bad
@import "foo/_bar.scss";
@import "_bar.scss";
@import "_bar";
@import "bar.scss";
// good
@import "foo/bar";
@import "bar";
Use 4 space indentation.
// bad: 2 spaces
.selector {
width: 100%;
}
// good: 4 spaces
.selector {
width: 100%;
}
Don't write leading zeros for numeric values with a decimal point.
// bad: unnecessary leading zero
.selector {
padding: 0.5em;
}
// good: no leading zero
.selector {
padding: .5em;
}
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() {
...
}
Overly nested rules will result in over-qualified CSS that could prove hard to maintain, output unnecessary selectors and is generally considered bad practice.
// bad: deeply nested
.one {
.two {
.three {
.four {
...
}
}
}
}
// good
.three {
&:hover {
...
}
&:visited {
...
}
}
Using a class selector with the @extend
statement statement usually results in
more generated CSS than when using a placeholder selector. Furthermore, Sass
specifically introduced placeholder selectors in order to be used with @extend
.
// bad: extending a class
.selector {
@extend .clearfix;
}
// good: extending a placeholder
.selector {
@extend %clearfix;
}