CSSStylelint

Stylelint

Stylelint is a linter for CSS (and CSS-like syntaxes such as Sass and Less) — the same role that ESLint plays for JavaScript. It parses your stylesheets and flags real errors, deprecated or browser-incompatible patterns, and formatting inconsistencies before they ever reach a code review, and it can be run locally, in an editor, in CI, or as a pre-commit hook.

Installing and configuring

Bash
npm install --save-dev stylelint stylelint-config-standard
stylelint-config-standard is the most widely used shareable config — a sensible, opinionated baseline ruleset maintained by the Stylelint team. Extending it means you don't have to hand-pick and configure every rule yourself:

JSON
{
  "extends": ["stylelint-config-standard"],
  "rules": {
    "color-hex-length": "long",
    "selector-class-pattern": null,
    "custom-property-pattern": null,
    "no-descending-specificity": null
  }
}
This file is typically saved as .stylelintrc.json (or .stylelintrc, or a stylelint key in package.json). The rules block above overrides three specific defaults — for example, disabling selector-class-pattern because the project's naming convention (say, BEM-style names) doesn't match the config's default expectation.
Running it

Bash
npx stylelint "src/**/*.css"
npx stylelint "src/**/*.css" --fix   # auto-fix what can be auto-fixed
What it typically catches

Category

Example problem it catches

Duplicate selectors

The same selector (.btn) declared twice in one file, where the second silently overrides the first

Invalid property values

color: #12345 (wrong hex length) or a typo'd value like postion: absolute

Deprecated / non-standard syntax

Vendor-prefixed properties that no longer need a prefix for your target browsers

Specificity issues

A later rule with lower specificity than an earlier one targeting the same property, which can silently fail to apply

Formatting consistency

Inconsistent indentation, missing trailing semicolons, mixed quote styles across a codebase

CSS
/* Stylelint would flag several problems here: */
.btn {
  Color: #fff;       /* invalid casing on the property name */
  background: #fff;
  background: #FFFFFF; /* duplicate property in the same rule */
}

.btn {                /* duplicate selector — easy to miss in a big file */
  padding: 10px;
}
Works with Sass and Less too
With the right syntax package (postcss-scss, postcss-less), Stylelint can lint preprocessor source files directly — catching problems in your .scss partials before they're even compiled to CSS.
Integrating into CI and pre-commit hooks

Running Stylelint manually catches problems, but running it automatically is what actually keeps a team consistent over time. Two common integration points:

  • CI pipeline — add a stylelint step to your GitHub Actions/CI config so a pull request with lint errors fails the build rather than merging.

  • Pre-commit hook — pair Stylelint with lint-staged and a Git hook manager (like Husky, which this project already uses for other checks) so only the changed CSS files are linted on every commit, keeping the check fast.

JSON
{
  "lint-staged": {
    "*.css": ["stylelint --fix"]
  }
}
Start with --fix, then tighten the ruleset gradually
Adding Stylelint to an existing, older codebase can surface hundreds of pre-existing violations at once. Run --fix first to clear the easy formatting issues automatically, then enable stricter rules incrementally rather than trying to reach a perfectly clean report on day one.