โ† Back to DevBytes

Stylelint: Complete Configuration Guide

Stylelint: Complete Configuration Guide

Stylelint is a powerful, modern linter for CSS and CSS-like languages such as SCSS, Sass, Less, and CSS-in-JS. It helps teams enforce consistent conventions, catch errors early, and maintain a clean, readable stylesheet codebase. In this guide, we will walk through everything you need to know to configure Stylelint effectively, from installation to advanced customization.

What Is Stylelint?

Stylelint is an open-source linter written in JavaScript that analyzes your stylesheets and flags problems based on a configurable set of rules. Unlike older tools that only checked formatting, Stylelint can enforce naming conventions, detect duplicate properties, prevent vendor prefix mistakes, and even validate values against custom logic. It is plugin-driven, highly configurable, and integrates smoothly with most modern build pipelines.

Why Stylelint Matters

Installation

Start by installing Stylelint and a recommended configuration as development dependencies. The most common starting point is stylelint-config-standard, which bundles a sensible set of rules.

npm install --save-dev stylelint stylelint-config-standard

If you work with SCSS, also install the SCSS plugin and shared config:

npm install --save-dev stylelint-config-standard-scss stylelint-scss

Creating a Configuration File

Stylelint looks for a configuration file named .stylelintrc.json, .stylelintrc.js, .stylelintrc.mjs, or a stylelint key inside package.json. The JSON format is the most common and easiest to maintain.

{
  "extends": "stylelint-config-standard",
  "rules": {
    "indentation": 2,
    "no-duplicate-selectors": true,
    "color-hex-length": "long",
    "declaration-block-no-redundant-longhand-properties": true
  }
}

The extends field lets you inherit rules from a shared configuration. The rules field overrides or adds specific rules on top of the extended config.

Understanding Rules

Each rule can be set to null (disabled), true (enabled with defaults), or an array where the second element is the configuration. For example:

{
  "rules": {
    "at-rule-no-unknown": true,
    "color-no-invalid-hex": true,
    "declaration-property-unit-allowed-list": {
      "line-height": ["unitless", "em", "rem"]
    },
    "selector-class-pattern": "^[a-z][a-zA-Z0-9]+$",
    "max-nesting-depth": 3
  }
}

Rules are grouped into categories such as possible errors, limit language features, and stylistic issues. Possible errors are enabled by default in most shared configs because they catch real bugs.

Disabling Rules Inline

Sometimes you need to bypass a rule for a specific block. Stylelint supports inline comments for this purpose:

/* stylelint-disable-next-line color-no-hex */
.button {
  background-color: #ff0000;
}

/* stylelint-disable selector-class-pattern */
.old-legacy-class {
  color: red;
}
/* stylelint-enable selector-class-pattern */

Use these sparingly. Overuse defeats the purpose of linting and signals that your config may need adjustment.

Working with Plugins

Plugins extend Stylelint with custom rules. A popular example is stylelint-scss, which adds SCSS-specific checks like at-rule-no-unknown for SCSS directives.

{
  "plugins": ["stylelint-scss"],
  "rules": {
    "at-rule-no-unknown": null,
    "scss/at-rule-no-unknown": true,
    "scss/dollar-variable-pattern": "^[a-z][a-zA-Z0-9]+$"
  }
}

Notice that we disable the built-in at-rule-no-unknown and enable the SCSS-specific version instead. This prevents Stylelint from flagging valid SCSS directives like @include or @use.

Using Overrides

When your project mixes different stylesheet types, overrides let you apply different rules to different files. This is useful when you have both plain CSS and SCSS in the same repository.

{
  "extends": "stylelint-config-standard",
  "overrides": [
    {
      "files": ["**/*.scss"],
      "extends": "stylelint-config-standard-scss",
      "rules": {
        "scss/at-rule-no-unknown": true
      }
    },
    {
      "files": ["**/vendor/**/*.css"],
      "rules": {
        "no-duplicate-selectors": null
      }
    }
  ]
}

Running Stylelint

Add a script to your package.json to run Stylelint across your project:

{
  "scripts": {
    "lint:css": "stylelint \"**/*.{css,scss}\"",
    "lint:css:fix": "stylelint \"**/*.{css,scss}\" --fix"
  }
}

The --fix flag automatically corrects problems that are safely fixable, such as formatting and ordering issues. Run the linter with:

npm run lint:css

Integrating with Editor and CI

For real-time feedback, install the Stylelint extension for VS Code or your preferred editor. Configure it to validate on save and auto-fix where possible. In your VS Code settings:

{
  "stylelint.validate": ["css", "scss", "less"],
  "editor.codeActionsOnSave": {
    "source.fixAll.stylelint": "explicit"
  }
}

For CI pipelines, add Stylelint to your workflow. Here is an example using GitHub Actions:

name: Lint CSS
on: [push, pull_request]
jobs:
  stylelint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm run lint:css

Ignoring Files

Create a .stylelintignore file to exclude vendored or generated stylesheets:

node_modules/
dist/
build/
**/vendor/**
*.min.css

Alternatively, use the ignoreFiles property inside your configuration file:

{
  "ignoreFiles": ["dist/**/*", "node_modules/**/*"]
}

Customizing Severity Levels

By default, rule violations are reported as errors. You can downgrade specific rules to warnings using the severity option:

{
  "rules": {
    "selector-class-pattern": [true, {
      "severity": "warning"
    }],
    "max-nesting-depth": [3, {
      "severity": "warning"
    }]
  }
}

This is useful when migrating a legacy codebase. You can start with warnings for rules you plan to enforce later, then promote them to errors once the codebase is clean.

Best Practices

Example: Pre-commit Hook with lint-staged

Install the necessary tools:

npm install --save-dev husky lint-staged

Configure lint-staged in your package.json:

{
  "lint-staged": {
    "*.{css,scss}": "stylelint --fix"
  }
}

Set up the hook:

npx husky init
echo "npx lint-staged" > .husky/pre-commit

Now, every commit will automatically lint and fix staged stylesheet files.

Conclusion

Stylelint is an indispensable tool for any team serious about stylesheet quality. By starting with a shared configuration, layering in project-specific rules, and integrating the linter into your editor and CI pipeline, you can catch mistakes early and keep your stylesheets maintainable as they grow. The key is to begin with sensible defaults, introduce stricter rules gradually, and document any exceptions clearly. With a well-tuned Stylelint setup, your team will spend less time debating formatting and more time building great interfaces.

๐Ÿ›  Tools from DevBytes

Inventory Tracker Pro โ€” Excel inventory system, low-stock alerts ยท $19
AI Dev Kit for Mac โ€” local AI dev environment templates ยท $9.99
KeyMapper for Mac โ€” custom keyboard shortcut toolkit ยท $7.99

โ† Back to all articles