Linting SCSS with sass-lint

Complex projects always require multiple developers and design heavy web sites are no exception. Sass/SCSS is still our language of choice when writing CSS, both for its wide support and flexibility. The latter can be a double-edged sword when it comes to maintainability with each developer bringing their own interpretation to the language's syntax. One way to solve this is with sass-lint, a Node-based linting tool, to keep everyone on the same page when writing Sass/SCSS code.

We've used sass-lint on a few projects now, most notably a large-scale CMS with dozens of components supported by 8-10 developers. Like other linters, rules are enforced via a .sass-lint.yml rules file and developers can determine what triggers either an error or warning. The syntax for a rule is pretty easy to grok:

rules:
  class-name-format:
    - 2
    - convention: hyphenatedlowercase

All rules are indented under rules:. In the example above we are enforcing class name format via class-name-format:. - 2 tells sass-lint to throw an error if there is a validation (0 disarms, 1 is a warning). - convention: hyphenatedlowercase tells the linter to enforce a specific style of class name. In this case we're going with hyphenated lowercase class names, or something like this: .tooltip-content. Based on the above rule, .TOOLTIPcontent would force sass-lint to throw an error that might look like this:

scss/base/_globals.scss
  452:2  error  Class '.TOOLTIPcontent' should be written in lowercase with hyphens  class-name-format

Luckily for those perfectionists with deadlines, all the available rules for sass-lint can be found in the repo via the rules documentation. If you need a little help getting started you can check out our base rules file.

What if you need to make an exception? What if some third-party code forces you to use .TOOLTIPContent? That's simple enough with Sass/SCSS comments:

// sass-lint:disable class-name-format
.TOOLTIPcontent {
  position: absolute;
}
// sass-lint:enable class-name-format

Since class-name-format impacts the whole block we need to disable and reenable it, but for most other rules you can handle everything on a single line:

// sass-lint:disable class-name-format
.TOOLTIPcontent {
  position: absolute;
  top: 10px; left: 20px; // sass-lint:disable one-declaration-per-line
}
// sass-lint:enable class-name-format

If you have the need to be especially heavy-handed, you can use sass-lint:disable-all and sass-lint:enable-all as needed. Need to go surgical? You can separate rules via commas: sass-lint:disable hex-notation, indentation.

Using sass-lint

Now that you're convinced to start linting your Sass/SCSS code, how do actually go about it? Installation couldn't be simpler with sass-lint:

npm install -g sass-lint

sass-lint comes with a handy CLI tool which might be enough for most situations:

sass-lint -c .sass-lint.yml '**/*.scss' -v -q

However, linting is the type of thing you want to do as you code. Several popular editors have plugins that allow you to do just that:

There's a good chance your favorite editor has a plugin that uses sass-lint. An alternative is to integrate sass-lint into your build tools or linting your Sass/SCSS code after each save via watch-like tools. This sort of approach is best left to future articles.

While just one tool in our ever-growing box, sass-lint has helped us increase developer productivity and deliver higher quality code to client development teams. Passive linting has eliminated some of the tedium of code reviews and feels like the only way to work. Happy linting!