To use stylelint to lint SCSS files, install stylelint:
npm install stylelint --save-dev
and install stylelint-scss:
npm install stylelint --save-dev
Stylelint expects a default config called .stylelintrc
, which is a JSON, although a
.stylelintrc.yaml
in YAML can also be used. Below is a "sensible" (at least for me) config.
It:
- extends the "recommended config"
- uses a couple of plugins to provide additional lints
- proceeds to list all the rules the linter should check
For it to work, it might be necessary to install with npm the following dependencies:
npm i -g stylelint-scss stylelint-declaration-block-no-ignored-properties stylelint-high-performance-animation postcss postcss-value-parser
---
extends: C:\Users\contivero\AppData\Roaming\npm\node_modules\stylelint-config-recommended
# These plugins need to be installed with npm
plugins:
- stylelint-scss
- stylelint-declaration-block-no-ignored-properties
- stylelint-high-performance-animation
rules:
scss/selector-no-redundant-nesting-selector: true
scss/at-if-closing-brace-newline-after: always-last-in-chain
scss/at-else-closing-brace-newline-after: always-last-in-chain
plugin/declaration-block-no-ignored-properties: true
plugin/no-low-performance-animation-properties: true
no-descending-specificity:
at-rule-no-unknown:
scss/at-rule-no-unknown: true
color-no-invalid-hex: true
font-family-no-duplicate-names: true
font-family-no-missing-generic-family-keyword: true
function-calc-no-unspaced-operator: true
function-linear-gradient-no-nonstandard-direction: true
string-no-newline: true
unit-no-unknown: true
property-no-unknown: true
keyframe-declaration-no-important: true
declaration-block-no-duplicate-properties:
- true
- ignore:
- consecutive-duplicates
declaration-block-no-shorthand-property-overrides: true
block-no-empty: true
selector-pseudo-class-no-unknown: true
selector-pseudo-element-no-unknown: true
selector-type-no-unknown: true
media-feature-name-no-unknown: true
comment-no-empty: true
no-duplicate-at-import-rules: true
no-duplicate-selectors: true
no-empty-source: true
no-extra-semicolons: true
no-invalid-double-slash-comments: true
function-url-no-scheme-relative: true
shorthand-property-no-redundant-values: true
value-no-vendor-prefix: true
property-no-vendor-prefix: true
declaration-block-no-redundant-longhand-properties: true
media-feature-name-no-vendor-prefix: true
at-rule-no-vendor-prefix: true
no-unknown-animations: true
color-hex-case: lower
font-weight-notation:
- numeric
- ignore:
- relative
function-comma-newline-after: always-multi-line
function-comma-space-after: always-single-line
function-comma-space-before: never
function-max-empty-lines: 0
function-name-case: lower
function-parentheses-space-inside: never-single-line
function-url-quotes: never
function-whitespace-after: always
number-no-trailing-zeros: true
string-quotes: double
length-zero-no-unit: true
unit-case: lower
value-keyword-case:
- lower
- ignoreKeywords:
- currentcolor
value-list-comma-newline-after: always-multi-line
value-list-comma-newline-before: never-multi-line
value-list-comma-space-after: always-single-line
value-list-comma-space-before: never
value-list-max-empty-lines: 0
custom-property-empty-line-before: never
property-case: lower
declaration-bang-space-after: never
declaration-bang-space-before: always
declaration-colon-space-after: always-single-line
declaration-colon-space-before: never
declaration-empty-line-before: never
declaration-block-semicolon-newline-after: always
declaration-block-semicolon-newline-before: never-multi-line
declaration-block-semicolon-space-after: always-single-line
declaration-block-semicolon-space-before: never
declaration-block-trailing-semicolon: always
block-closing-brace-empty-line-before: never
block-closing-brace-newline-after:
- always
- ignoreAtRules:
- if
- else
block-closing-brace-newline-before: always-multi-line
block-opening-brace-newline-after: always-multi-line
block-opening-brace-space-before: always
selector-attribute-brackets-space-inside: never
selector-attribute-operator-space-after: never
selector-attribute-operator-space-before: never
selector-attribute-quotes: never
selector-combinator-space-after: always
selector-combinator-space-before: always
selector-descendant-combinator-no-non-space: true
selector-pseudo-class-case: lower
selector-pseudo-class-parentheses-space-inside: never
selector-pseudo-element-case: lower
selector-pseudo-element-colon-notation: double
selector-type-case: lower
selector-list-comma-newline-after: always-multi-line
selector-list-comma-newline-before: never-multi-line
selector-list-comma-space-after: always-single-line
selector-list-comma-space-before: never
rule-empty-line-before:
- always-multi-line
- except:
- inside-block
ignore:
- after-comment
media-feature-colon-space-after: always
media-feature-colon-space-before: never
media-feature-name-case: lower
media-feature-parentheses-space-inside: never
media-feature-range-operator-space-after: always
media-feature-range-operator-space-before: always
media-query-list-comma-newline-after: always-multi-line
media-query-list-comma-space-after: always-single-line
media-query-list-comma-space-before: never
indentation: tab
linebreaks: unix
max-empty-lines: 2
no-eol-whitespace: true
no-empty-first-line: true
For a more pedantinc lint, add the following to some other file, say .stylelintrc-pedantic
:
"selector-no-qualifying-type": true,
"no-descending-specificity": true,
"max-nesting-depth": 3,
"selector-no-vendor-prefix": true,
"scss/selector-no-redundant-nesting-selector": true,
"scss/at-if-closing-brace-newline-after": "always-last-in-chain",
"scss/at-else-closing-brace-newline-after": "always-last-in-chain",
"plugin/stylelint-no-indistinguishable-colors": true,
"plugin/declaration-block-no-ignored-properties": true,
"plugin/no-low-performance-animation-properties": true,
"at-rule-no-unknown": null,
"scss/at-rule-no-unknown": true,
(make sure to delete those repeated ones, like no-descending-specificity
).
To use the pedantic config, we can use the --config
flag:
stylelint --config .stylelintrc-pedantic path/to/input.scss