Linting CSS with stylelint

I like to keep my CSS tidy and consistently formatted. One of the tools I use to help with that is stylelint. If anyone’s curious, this post explains how I configure it.

You can run stylelint in multiple ways. I use it via the PostCSS plugin, but you can run it from the command line, from within code editors like Atom and Sublime Text, or call it from Node scripts. There are different ways to specify the configuration, but I always use a .stylelintrc config file in the root of my projects.

This is the configuration I use:

"at-rule-empty-line-before": "always",
"block-closing-brace-newline-after": "always",
"block-closing-brace-newline-before": "always",
"block-no-empty": true,
"block-no-single-line": true,
"block-opening-brace-newline-after": "always",
"block-opening-brace-space-before": "always",
"color-hex-case": "lower",
"color-hex-length": "short",
"color-no-invalid-hex": true,
"color-named": "never",
"comment-empty-line-before": "always",
"comment-whitespace-inside": "always",
"custom-property-no-outside-root": true,
"declaration-bang-space-after": "never",
"declaration-bang-space-before": "always",
"declaration-block-no-shorthand-property-overrides": true,
"declaration-block-semicolon-newline-after": "always",
"declaration-block-semicolon-space-before": "never",
"declaration-block-trailing-semicolon": "always",
"declaration-colon-space-after": "never",
"declaration-colon-space-before": "never",
"function-calc-no-unspaced-operator": true,
"function-comma-space-after": "always",
"function-comma-space-before": "never",
"function-parentheses-space-inside": "never",
"function-url-quotes": "none",
"indentation": "tab",
"max-empty-lines": 3,
"media-feature-colon-space-after": "never",
"media-feature-colon-space-before": "never",
"media-feature-no-missing-punctuation": true,
"media-query-list-comma-newline-after": "never-multi-line",
"media-query-list-comma-newline-before": "never-multi-line",
"media-query-parentheses-space-inside": "never",
"number-leading-zero": "always",
"number-zero-length-no-unit": true,
"rule-nested-empty-line-before": "never",
"rule-non-nested-empty-line-before": "never",
"selector-combinator-space-after": "always",
"selector-combinator-space-before": "always",
"selector-list-comma-newline-after": "always",
"selector-list-comma-newline-before": "never-multi-line",
"selector-list-comma-space-before": "never",
"selector-pseudo-element-colon-notation": "double",
"selector-type-case": "lower",
"string-quotes": "double",
"value-list-comma-space-after": "always",
"value-list-comma-space-before": "never"

So what does that make my CSS look like? First, here’s a snippet that stylelint will go mad about:

.thing
{
	padding: 24px 0;
	background: #EEE;
	color: #333333
}
.thing:before {
	display: inline-block;
	background: url("icon.svg");
	width: 24px;
    height: 24px;
	content:'';
}

.thing h2, .thing p {margin-top:12px;}
.thing-thing {
	background-color: rgba(0,0,0,0.4);
	min-width:calc(50% - 100px)!important;
}
@media only screen and (min-width : 600px) {
.thing {
	padding:48px 0;
}
}

Here’s the same snippet cleaned up so that stylelint with the above configuration won’t complain:

.thing {
	padding:24px 0;
	background:#eee;
	color:#333;
}
.thing::before {
	display:inline-block;
	background:url(icon.svg);
	width:24px;
	height:24px;
	content:"";
}
.thing h2,
.thing p {
	margin-top:12px;
}
.thing-thing {
	background-color:rgba(0, 0, 0, 0.4);
	min-width:calc(50% - 100px) !important;
}

@media only screen and (min-width:600px) {
	.thing {
		padding:48px 0;
	}
}

Most likely this is not exactly how you prefer to format your CSS. For instance I know that many people use a space after the colon in declarations and some like to separate rules with an empty line. Luckily that is totally configurable with stylelint.

I don’t really have to think about most of these rules while writing CSS since I use CSScomb to fix them automatically if I make a mistake. So I always have a Grunt watch task running that runs CSScomb before stylelint, which reduces the number of errors I have to fix manually. But since I write the changes CSScomb makes back to the source CSS I always see the linted CSS and it becomes second nature, as does the sort order enforced by CSScomb (more on that in a future post, I hope). There is also an ongoing discussion about adding autocorrect to stylelint, which could make CSScomb redundant if you use stylelint.

Whether you agree with the rules I use or not, linting your CSS is a good idea. Find a stylelint implementation that fits into your workflow, configure rules to match your preferences and start linting.

Posted on April 3, 2016 in CSS