Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Unreleased
6.0.0-alpha.0 — 2026–10–19
Changed
Namespaces for custom syntaxes
The rules under their core names no longer read an SCSS or Less stylesheet, or a styled template: such a file now gets one warning naming the namespace that holds the same rules with the same options and documentation, and nothing else of it is checked. Where the namespace's copy of the rule is configured over the file, in an overrides block or through a preset, that copy reads it and the core name says nothing. An option a namespace's syntax cannot carry is refused there instead: Less refuses an at-rule name in upper case, so upper is an invalid option of @stylistic/less/at-rule-name-case, since a stylistic fix must never leave a file its compiler refuses.
Rename the rules in the overrides block that sets customSyntax — @stylistic/scss/indentation in place of @stylistic/indentation, and less or styled in place of scss for the other two. Nothing else in the configuration changes, and a namespace reads plain CSS exactly as the core does. A configuration that names no syntax anywhere is unaffected: such a file is parsed as CSS, which is the family the core's copies read, and it is read by them under the same names and with the same warnings as before.
The core is now written for plain CSS alone, so a construct only a preprocessor spells is read as the CSS it is: a Sass module (ns.$a), a placeholder selector (%a), a nested property (font: { … }), a comment opened by a double slash, an at-rule carrying neither block nor parameters, and a value opening with @. A plain CSS file spelling any of those may meet warnings it used to escape.
The new defineStylistic and defineStylisticOverride functions (see below) name the syntax once for the whole block, so the rules stay under their short names and you write no namespace at all.
A rule listed under two of these names over one stylesheet is now read once, by the copy of the stylesheet's own family — the core's over plain CSS, the namespace's over its syntax — and the other copies yield without a word; where the family's copy is not configured, the first listed copy whose namespace accepts the stylesheet reads it. A configuration listing the core and a namespace over the same files used to run every rule twice there and report every problem twice.
Expanding the scope of the rules
- The
named-grid-areas-alignmentrule now applies to thegrid-templateandgridproperties too, and not only togrid-template-areas(see #45). Where your code spells those shorthands, the rule may start asking for corrections or writing them under--fix. For finer control use its new option (see below).
Independence from the order of the rules
Many rules now read the settings of other rules and what they will write in the same text, so what --fix leaves no longer depends on where the configuration lists a rule (see #352, #354, #355, #477, #502). A rule writing a line break, for one, asks the linebreaks rule which break to write, wherever that rule is listed. Where a neighbor's write changes whether the rule's own option asks anything at all, the text is read as the whole fix leaves it, and a file that needed a second --fix run rests on one. Expect some new autocorrections in your code.
End-of-line characters
The plugin now reads a line break the way PostCSS and Stylelint do: a line feed, alone or behind the carriage return of a Windows pair. A bare carriage return and a form feed are plain whitespace, so a file broken with either is one line to every rule about breaks, empty lines and multi-line lists, and no rule reports a position your editor cannot show. The linebreaks rule still tells \n from \r\n.
Passing over @charset
The at-rule-name-case, at-rule-name-space-after, at-rule-name-newline-after, at-rule-semicolon-space-before and string-quotes rules no longer warn about a @charset or write into it, in any spelling: the encoding declaration is a byte sequence the browser reads before parsing rather than an at-rule, and every other spelling of it is ignored. Stylelint's at-charset-rule-no-invalid rule judges the spelling instead, so a CSS file holding a @charset now gets one warning asking you to enable that rule where your configuration leaves it off. The unicode-bom rule under "always" now warns about the option itself over a CSS file whose first node is a @charset, since the mark would keep the declaration from working; set "never" or leave the rule unset for such files.
Conflicting settings
The plugin now refuses a configuration holding two settings that conflict with each other, such as value-list-comma-newline-after: "always-multi-line" beside value-list-comma-space-after: "always": the run stops with a configuration error naming both settings and what to change (see #743). Where your configuration holds such a pair, change one of the two as the message says, or turn one of them off. The types of defineStylistic refuse such a pair in the editor.
Added
New rules
- The
aspect-ratio-notationrule, which specifies how the value ofaspect-ratiois written (see #18). - The
declaration-block-single-line-max-declarationsrule, which limits the number of declarations within a single-line declaration block (see #639). Stylelint 18 removes the rule of its own, and this one takes the same option, so a configuration moves it by renaming it to@stylistic/declaration-block-single-line-max-declarations. It reads more than Stylelint's did — the single-line block of an at-rule as well (see #640) — and it is autofixable, which Stylelint's never was (see #641). - The
value-slash-newline-beforeandvalue-slash-newline-afterrules, which require a newline or disallow whitespace on either side of the same solidus (see #622). - The
value-slash-space-before,value-slash-space-after,media-feature-slash-space-beforeandmedia-feature-slash-space-afterrules, which require a single space or disallow whitespace on either side of the solidus of a value or of a media feature's ratio (see #548).
New options
- The
block-closing-brace-empty-line-beforerule now takes alast-nestedvalue in itsexceptoption (see #60), which reverses the primary option where a chain of nested blocks ends — at a block nested in another one and holding no block of its own — so that under"never"the empty line before such a brace is asked for, and under"always-multi-line"it is not. - The
max-line-lengthrule now has an additionaltabSizeoption (see #10), which measures a tab to the next tab stop of that width, so a file indented with tabs is as long as the editor's ruler shows. - The
named-grid-areas-alignmentrule now has an additionalalignColumnsoption (see #45), which lays the line names and the sizes of agrid-templateorgridshorthand out as columns of a table.
New autofixes
- The
at-rule-name-newline-afterrule is now autofixable (see #696). Expect--fixto write the newlines the rule used to only ask for. Where your configuration also listsat-rule-name-space-afterunderalways, the two ask for different things in the same place, and the plugin now refuses the pair as conflicting settings. A@charsetis reported but left as written, since breaking its head can leave the stylesheet declaring no encoding. - The
at-rule-semicolon-space-beforerule is now autofixable (see #697). Expect--fixto write the whitespace the rule used to only ask for. - The
block-closing-brace-space-afterrule is now autofixable (see #698). Expect--fixto write the whitespace the rule used to only ask for. - The
media-query-list-comma-newline-beforerule is now autofixable (see #699). Expect--fixto write the newlines the rule used to only ask for. Where your configuration also listsmedia-query-list-comma-space-beforeasking for something else of that same run —media-query-list-comma-newline-before: "always-multi-line"besidemedia-query-list-comma-space-before: "never", for one — the plugin now refuses the pair as conflicting settings. - The
unicode-bomrule is now autofixable (see #700). Expect--fixto write or take off the byte order mark the rule used to only ask for. - The
value-list-comma-newline-beforerule is now autofixable (see #701). Expect--fixto write the newlines the rule used to only ask for. Where your configuration also listsvalue-list-comma-space-beforeasking for something else of that same run —value-list-comma-newline-before: "always-multi-line"besidevalue-list-comma-space-before: "never", for one — the plugin now refuses the pair as conflicting settings.
New features
- The plugin now ships a recommended preset (see #745):
"extends": ["@stylistic/stylelint-plugin/recommended"]sets every rule of the plugin that has an answer the same for every project, for plain CSS and, over.scssand.lessfiles, for SCSS and Less; a setting of your own inruleswins over it. It names no parser, so a project installs none, and an.scssor a.lessfile is read by the copies of its syntax as soon as the project names that syntax with oneoverridesentry of its own, and is read as CSS by the@stylistic/names until then, as before. The table it is built out of is exported asconfigs.recommendedRulesbeside the preset, for a configuration that projects it under thestylednamespace or changes one setting under every name at once. - The package now exports the
defineStylisticanddefineStylisticOverridefunctions for a JavaScript configuration (see #624). You name the rules by their short names and the syntax once for the whole block: an editor completes the names and the options, and the compiler refuses a rule, an option, a key or a syntax the plugin does not take. - The plugin now ships a type declaration for what it exports, so a TypeScript configuration or a script importing the package reads the plugin list as
Plugin[]rather than asany. Nothing about configuring the plugin changes. - The plugin now says so when it is listed in
extendsinstead ofplugins(see #14). Such a configuration used to fail with every@stylistic/rule of it reported as unknown; the run now stops with a configuration error naming the preset to extend instead, or the field to move the package to.
By the way, the documentation now lives at stylelint-stylistic.github.io.
Fixed
The rules below used to pass some code over in silence. They now warn on it, so code that used to be clean may need corrections.
- The
declaration-block-semicolon-newline-after,declaration-block-semicolon-newline-before,declaration-block-semicolon-space-afteranddeclaration-block-semicolon-space-beforerules now check the declarations of an inlinestyleattribute (see #49). - The
declaration-colon-space-afterrule now looks for the whitespace after the colon where a custom property whose value holds a comment actually keeps it (see #109) (@VChet). - The
indentationrule now reports every mis-indented line of an at-rule's parameters holding comments, at the line and column the file spells (see #65). - The
indentationrule now corrects every mis-indented line of an at-rule, and not only one of them (see #64). - The
max-empty-linesrule now counts the empty lines inside a Sass nested property written with a value, and puts every warning behind such a property, an end-of-line comment or a Less mixin call's!importanton the line and column the file spells (see #583).
And also a huge number of false negatives and other bugs found by tools and agents, which may likewise require you to fix the code.
5.3.1 — 2026–09–29
Fixed
- The
block-opening-brace-space-beforerule no longer removes a comment standing between the selector and the opening brace when fixing (see #63). - The
indentationrule no longer damages a declaration whose multi-line value holds comments when fixing (see #62). - The
selector-combinator-space-beforerule no longer reports a combinator that opens a selector when a comment stands in front of it (see #66). - The
indentationrule no longer raises the whole of a selector list by a level when one selector of it is a pseudo-class broken over several lines (see #74). - The
no-eol-whitespacerule now trims every line of a comment when fixing, and not only the lines up to the first quotation mark in it (see #67). - The
string-quotesrule no longer loses its bearings in a declaration's value or an at-rule's parameters holding a comment (see #61, #33). - The
at-rule-semicolon-newline-afterrule no longer reports an at-rule whose semicolon is followed by a comment on a line of its own, and no longer breaks that comment's line when fixing (#748) (@christianvuerings).
5.3.0 — 2026–08–09
Added
- The
function-comma-newline-afterrule now has an additionalignoreFunctionsoption (see #78). - The
function-comma-newline-beforerule now has an additionalignoreFunctionsoption (see #81). - The
function-comma-space-afterrule now has an additionalignoreFunctionsoption (see #82). - The
function-comma-space-beforerule now has an additionalignoreFunctionsoption (see #83).
5.2.1 — 2026–07–01
Fixed
- The protocol in the repository's metadata URL now meets current requirements (#79) (@BowenMilner).
5.2.0 — 2026–05–20
Added
- The
declaration-block-semicolon-newline-beforerule is now autofixable.
Fixed
- An exception for an empty custom property value has been added to the
declaration-block-semicolon-newline-beforeanddeclaration-colon-space-afterrules: the--custom-prop: ;and--custom-prop:;variants are now considered valid (see #50).
5.1.0 — 2026–03–28
Added
- The
no-multiple-whitespacesrule, which disallows multiple whitespaces between property values and function arguments.
Fixed
- The dependencies have now been updated to versions that include security fixes.
5.0.1 — 2026–01–22
Fixed
- The
selector-pseudo-class-parentheses-space-insiderule no longer triggers false positives in multiline pseudo-classes.
5.0.0 — 2026–01–15
Changed
- The plugin now requires:
stylelintversion17.0.0or highernode.jsversion20.19.0or higher
4.0.1 — 2026–01–15
Fixed
Multiline pseudos are now aligned correctly with the
@stylistic/indentationrule.Before:
css.foo:where( :not( .bar, .baz ) ) {}Now:
css.foo:where( :not( .bar, .baz ) ) {}
4.0.0 — 2025–07–22
Changed
- The plugin now requires
stylelintversion16.22.0or higher.
3.1.3 — 2025–06–25
Fixed
stylelinthas been moved fromdependenciestodevDependencies. This may potentially fix some errors (see Stylelint's documentation regardingpeerDependenciesand PRs that explain the motivation behind this decision).postcsshas been moved fromdevDependenciestodependencies. This fixes the “Cannot find packagepostcss” and “Named exportInputnot found” error in some environments.
3.1.2 — 2025–02–05
Fixed
- An explicit end position is now passed to all
reportcalls.
Thereportcalls no longer receive thelineargument, which was deprecated instylelint@16.13.0.
Previously, attempts to updatestylelintto16.13.0version resulted in multiple DeprecationWarning messages (#53) (@MorevM). - Added an exception to the
declaration-block-semicolon-space-beforerule for an empty value of a custom property: now both--custom-prop: ;and--custom-prop:;are considered valid even with theneverandnever-single-lineoptions.
You can find a detailed explanation in the original issue (#51) (@MorevM). - Fixed behavior of
baseIndentLeveloption ofindentationrule when used in non-CSS files (e.g. when usingpostcss-htmlsyntax) (#47) (@net-solution). - Fixed removing the starting indentation along with the blank line in the
no-empty-first-rulerule (#47) (@net-solution).
3.1.1 — 2024–10–04
Fixed
- Indentation checking for property values that use dynamic expressions when using
postcss-styled-syntaxis now disabled (#44) (@MorevM).
3.1.0 — 2024–09–23
Added
- The
messageArgsto 16 rules for custom message arguments. See stylelint documentation for details.
Fixed
3.0.1 — 2024–08–18
Fixed
- The
context.fix, which is deprecated instylelint@16.8.2, is no longer used. Previously, attempts to updatestylelintto16.8.2version resulted in multiple DeprecationWarning messages (#37).
3.0.0 — 2024–07–30
Changed
- The plugin now requires
stylelintversion16.8.0or higher.
2.1.3 — 2024–07–29
Fixed
- Dependencies are now updated, which fixes test fails (#29) (@ybiquitous).
2.1.2 — 2024–04–28
Fixed
2.1.1 — 2024–03–31
Fixed
block-closing-brace-empty-line-beforewith except: ["after-closing-brace"] false negatives for CSS Nesting (#22) (@firefoxic).named-grid-areas-alignmentfor single-line input (#21) (@MorevM).
2.1.0 — 2024–02–18
Added
2.0.0 — 2023–12–20
Changed
- The repository renamed to
stylelint-stylisticand moved to the organization of the same name. - The plugin is published in
npmunder the new name@stylistic/stylelint-plugin. Therefore, you should:- change the former plugin name
stylelint-codeguideto the new one in the config, - remove the old
stylelint-codeguidepackage from dependencies - install the new
@stylistic/stylelint-pluginpackage.
- change the former plugin name
- The namespace of plugin rules has been renamed. Therefore, you should change the rules prefix from
codeguide/to@stylistic/in the config.
1.0.2 — 2023–12–12
Updated
- Stylelint to version
16.0.2, which fixes the use of plugins in Windows.
1.0.1 — 2023–12–10
Fixed
- Dependency definition.
1.0.0 — 2023–12–08
Changed
- The required version of Stylelint is now at least
v16.0.1. - The required version of Node.js is now LTS at least
v18.12, or at leastv20.9. - The plugin is now converted to a pure ES module.
0.3.2 — 2023–10–19
Updated
- Stylelint to
^15.11.0. - Node.js to
>=18.16.
0.3.1 — 2023–10–13
No meaningful changes.
0.3.0 — 2023–10–13
Changed
- Along with updating the plugin to this release, Stylelint needs to be updated to
v15.10.3as well.
Updated
- All code according to
stylelint@15.10.3. - Peer dependency —
stylelint@15.10.3.
0.2.2 — 2023–09–14
Fixed
- The path to the internal module.
0.2.1 — 2023–07–08
Fixed
- Any LTS version of Node.js on the 18th branch is now required (i.e. at least
18.12.0), not the latest. - Any version of Stylelint on the 15th branch is now required (i.e. at least
15.0.0), not the latest.
0.2.0 — 2023–07–01
Updated
- Peer dependency Stylelint to
15.9.0.
0.1.5 — 2023–07–01
Fixed
- All paths to docs.
0.1.4 — 2023–05–20
Changed
- Reorganized
package.json.
0.1.3 — 2023–03–28
Removed
- The
deprecatedflag from themetaof each rule.
0.1.2 — 2023–03–28
Fixed
Error [ERR_REQUIRE_ESM]: require() of ES Module.
0.1.1 — 2023–03–28
Added
- Babel until Stylelint is converted to ES Modules.
0.1.0 — 2023–03–28
Added
at-rule-name-caserule.at-rule-name-newline-afterrule.at-rule-name-space-afterrule.at-rule-semicolon-newline-afterrule.at-rule-semicolon-space-beforerule.block-closing-brace-empty-line-beforerule.block-closing-brace-newline-afterrule.block-closing-brace-newline-beforerule.block-closing-brace-space-afterrule.block-closing-brace-space-beforerule.block-opening-brace-newline-afterrule.block-opening-brace-newline-beforerule.block-opening-brace-space-afterrule.block-opening-brace-space-beforerule.color-hex-caserule.declaration-bang-space-afterrule.declaration-bang-space-beforerule.declaration-block-semicolon-newline-afterrule.declaration-block-semicolon-newline-beforerule.declaration-block-semicolon-space-afterrule.declaration-block-semicolon-space-beforerule.declaration-block-trailing-semicolonrule.declaration-colon-newline-afterrule.declaration-colon-space-afterrule.declaration-colon-space-beforerule.function-comma-newline-afterrule.function-comma-newline-beforerule.function-comma-space-afterrule.function-comma-space-beforerule.function-max-empty-linesrule.function-parentheses-newline-insiderule.function-parentheses-space-insiderule.function-whitespace-afterrule.indentationrule.linebreaksrule.max-empty-linesrule.max-line-lengthrule.media-feature-colon-space-afterrule.media-feature-colon-space-beforerule.media-feature-name-caserule.media-feature-parentheses-space-insiderule.media-feature-range-operator-space-afterrule.media-feature-range-operator-space-beforerule.media-query-list-comma-newline-afterrule.media-query-list-comma-newline-beforerule.media-query-list-comma-space-afterrule.media-query-list-comma-space-beforerule.no-empty-first-linerule.no-eol-whitespacerule.no-extra-semicolonsrule.no-missing-end-of-source-newlinerule.number-leading-zerorule.number-no-trailing-zerosrule.property-caserule.selector-attribute-brackets-space-insiderule.selector-attribute-operator-space-afterrule.selector-attribute-operator-space-beforerule.selector-combinator-space-afterrule.selector-combinator-space-beforerule.selector-descendant-combinator-no-non-spacerule.selector-list-comma-newline-afterrule.selector-list-comma-newline-beforerule.selector-list-comma-space-afterrule.selector-list-comma-space-beforerule.selector-max-empty-linesrule.selector-pseudo-class-caserule.selector-pseudo-class-parentheses-space-insiderule.selector-pseudo-element-caserule.string-quotesrule.unicode-bomrule.unit-caserule.value-list-comma-newline-afterrule.value-list-comma-newline-beforerule.value-list-comma-space-afterrule.value-list-comma-space-beforerule.value-list-max-empty-linesrule.