stylelint is a linting tool. A linter is an application that checks code for potential trouble spots, and enforces coding conventions according to a set of rules. You can, for instance, use linters to enforce tabs instead of spaces for indentation. stylelint can find problems such as duplicate selectors, invalid rules, or unnecessary specificity. These have the greatest impact on CSS maintainability.
Install stylelint as you would any other npm package:
npm install -g stylelint
Once installed, we’ll need to configure stylelint. Start by installing the standard configuration:
npm install -g stylelint-config-standard
Next, create a file named .styLeLintrc in your home directory. We’ll use this file to configure stylelint. Placing it in your home directory makes it available to all of your projects.
The .styLeLintrc file can use JSON (JavaScript Object Notation) or YAML (YAML Ain’t Markup Language) syntax. We’ll use JSON here.
Let’s extend the standard configuration. Add the following to your .styLeLintrc file:
{
“extends”: “stylelint-config-standard”
}
This is enough to start linting our CSS.
1. Using stylelint and Understanding Its Output
Type the following in the command line:
stylelint style.css
To recursively lint all CSS files in a directory, use the following:
stylelint ./css/**/*.css
stylelint can also lint CSS that’s embedded in HTML files using the <styLe> element. Pass the path to an HTML file as the argument. When stylelint finishes analyzing your CSS, you’ll see output resembling what’s shown below.
The first column indicates the line number and character position of the rule violation. For example, 4:2 indicates that our first rule violation occurs on line 4 of style.css , beginning with the second character.
Next, stylelint describes what it expected to see based on the rules defined in the standard configuration. Expected “#ffffff” to be “#ffffff” indicates that we should have used lowercase hexadecimal color notation. The last column indicates the name of the violated rule— coLor-hex-case . Our second error occurs on the same line. We’ve also violated the coLor-hex-Length rule by using a six-digit hexadecimal color value instead of a more concise, three-digit version.
As you can see from this output, the standard configuration is quite opinionated. It prefers an indentation of two spaces instead of tabs, and enforces a rule of one selector per line. Let’s make a few changes.
2. Configuring stylelint’s Rules
We can add or override stylelint rules by adding a rules property to .styLeLintrc . Remember that our .styLeLintrc file uses JSON. Each property needs to be enclosed in double straight quotation marks:
{
“extends”: “stylelint-config-standard”,
“rules”: {}
}
Now let’s decide what we’d like to change. We can view our current configuration using the following command:
stylelint –print-config ./
The –print-config flag requires a file path. We’ve installed stylelint and our configuration globally, so we can use any directory—in this case, our current path. Refer to the stylelint user guide for a complete list of rules and options.
Let’s change our current indentation from spaces to tabs. We’ll need to modify the indentation rule by adding it as a property of our ruLes object:
{
“extends”: “stylelint-config-standard”, “rules”: {
“indentation”: “tab”
}
}
Let’s also enforce single-line selector lists, with a space after each comma. In other words, we’ll allow selector lists formatted as follows:
h1, h2, h3, h4 {
font-family: ‘geomanistbold’;
}
But let’s also disallow multi-line selector lists, such as the example below:
h1, h2, h3, h4 {
font-family: ‘geomanistbold’;
}
For this, we’ll need to use a combination of four rules: seLector-List-comma-newLine-after , seLector-List-comma-newLine-before , seLector-List-comma-space-after and seLector- List-comma-space-before :
{
“extends”: “stylelint-config-standard”,
“rules”: {
“indentation”: “tab”,
“selector-list-comma-newline-after”: “never-multi-line”,
“selector-list-comma-newline-before”: “never-multi-line”,
“selector-list-comma-space-before”: “never”,
“selector-list-comma-space-after”: “always”
}
}
Now when we run styLeLint , we’ll see the following output. Notice that stylelint no longer makes a fuss about our indentation.
In Chapter 2, I mentioned selector specificity and how it affects CSS maintenance. stylelint includes a few rules that let us enforce low specificity. We’ll use one of them here: seLector- max-specificity . Let’s edit .styLeLintrc again to limit specificity to a maximum of 0,2,1:
{
“extends”: “stylelint-config-standard”,
“rules”: {
“indentation”: “tab”,
“selector-list-comma-newline-after”: “never-multi-line”, “selector-list-comma-newline-before”: “never-multi-line”, “selector-list-comma-space-before”: “never”,
“selector-list-comma-space-after”: “always”,
“selector-max-specificity”: “0,2,1”
}
}
With this rule, selectors such as .subnav a:hover won’t trigger warnings or errors, but selectors such as #menu or .features p:first-of-type::first-Letter will.
It’s not necessary to use a preset configuration with stylelint. You could remove the “extends” property and set your own style preferences using “rules” . A custom configuration may be the wiser choice if you find yourself overriding more than a few standard rules.
3. Using stylelint with npx
As mentioned above, global npm packages can cause troubles if you work on multiple Node.js projects. The good news is that we can use stylelint with npx too. That said, the process of using stylelint with npx is a little bit different.
First, we’ll need to install a local, directory-level version of styLeLint-config-standard :
npm install stylelint-config-standard
Using npm install without the -g flag installs the styLeLint-config-standard package in our current directory. It’s only available within this directory, rather than system-wide. Now we can use npx to run stylelint:
npx stylelint style.css
Keep in mind that we only need to install styLeLint-config-standard if we plan to use it in our .styLeListrc configuration. Otherwise, you can skip that step and just use whatever rules you’ve defined using the rules property.
Source: Brown Tiffany B (2021), CSS , SitePoint; 3rd edition.