noExcessiveSelectorComplexity (CSS)
Summary
Section titled “Summary”- Rule available since:
v2.6.7 - Diagnostic Category:
lint/nursery/noExcessiveSelectorComplexity - This rule doesn’t have a fix.
- The default severity of this rule is warning.
- Sources:
- Same as
css/selector-complexity
- Same as
How to configure
Section titled “How to configure”{ "linter": { "rules": { "nursery": { "noExcessiveSelectorComplexity": "error" } } }}Description
Section titled “Description”Limit how complex selectors can be, and disallow chosen parts of selectors.
Long selectors that mix many IDs, element names, attributes, and pseudo-classes are hard to read and hard to override. They also tie styles closely to the structure of the page, so small changes to the HTML can break them.
This rule lets you set a maximum for each kind of selector part, and list combinators, pseudo-classes, pseudo-elements, attributes, and attribute operators that aren’t allowed. The rule does nothing until at least one option is set.
Each selector in a comma-separated list is checked on its own. For example, #a, #b
contains two selectors with one ID each.
Selectors inside a pseudo-class such as :not(), :is(), or :has() are checked as
separate selectors, and don’t count toward the selector that contains them. For example,
#a:not(#b) contains two selectors with one ID each.
Nested selectors are checked as written, without combining them with the selectors of their parent rules.
Examples
Section titled “Examples”Invalid
Section titled “Invalid”{ "linter": { "rules": { "nursery": { "noExcessiveSelectorComplexity": { "level": "on", "options": { "maxIds": 1, "disallowPseudoClasses": [ "hover" ] } } } } }}#main #sidebar {}code-block.css:1:1 lint/nursery/noExcessiveSelectorComplexity ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ This selector has too many ID selectors: it has 2, but the limit is 1.
> 1 │ #main #sidebar {}
│ ^^^^^^^^^^^^^^
2 │
ℹ Complex selectors are hard to read and override, and break easily when the page structure changes.
ℹ Simplify the selector, for example by giving the element a class and selecting it directly.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
button:hover {}code-block.css:1:7 lint/nursery/noExcessiveSelectorComplexity ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ The pseudo-class :hover isn't allowed.
> 1 │ button:hover {}
│ ^^^^^^
2 │
ℹ The rule's configuration disallows this pseudo-class in selectors.
ℹ Rewrite the selector without it, for example by giving the element a class and selecting it directly.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
#main .sidebar,#footer {}
#main:not(#sidebar) {}
button:focus {}Options
Section titled “Options”maxIds
Section titled “maxIds”Default: no limit
The maximum number of ID selectors, such as #main, allowed in a single selector.
{ "linter": { "rules": { "nursery": { "noExcessiveSelectorComplexity": { "level": "on", "options": { "maxIds": 1 } } } } }}Invalid
Section titled “Invalid”#main > #sidebar {}code-block.css:1:1 lint/nursery/noExcessiveSelectorComplexity ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ This selector has too many ID selectors: it has 2, but the limit is 1.
> 1 │ #main > #sidebar {}
│ ^^^^^^^^^^^^^^^^
2 │
ℹ Complex selectors are hard to read and override, and break easily when the page structure changes.
ℹ Simplify the selector, for example by giving the element a class and selecting it directly.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
#main .sidebar {}maxTypes
Section titled “maxTypes”Default: no limit
The maximum number of type selectors allowed in a single selector. A type selector
matches elements by their tag name, such as div or a.
{ "linter": { "rules": { "nursery": { "noExcessiveSelectorComplexity": { "level": "on", "options": { "maxTypes": 2 } } } } }}Invalid
Section titled “Invalid”ul li a {}code-block.css:1:1 lint/nursery/noExcessiveSelectorComplexity ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ This selector has too many type selectors: it has 3, but the limit is 2.
> 1 │ ul li a {}
│ ^^^^^^^
2 │
ℹ Complex selectors are hard to read and override, and break easily when the page structure changes.
ℹ Simplify the selector, for example by giving the element a class and selecting it directly.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
li.item a {}maxAttributes
Section titled “maxAttributes”Default: no limit
The maximum number of attribute selectors, such as [type="text"], allowed in a single
selector.
{ "linter": { "rules": { "nursery": { "noExcessiveSelectorComplexity": { "level": "on", "options": { "maxAttributes": 1 } } } } }}Invalid
Section titled “Invalid”[name="email"][type="text"] {}code-block.css:1:1 lint/nursery/noExcessiveSelectorComplexity ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ This selector has too many attribute selectors: it has 2, but the limit is 1.
> 1 │ [name="email"][type="text"] {}
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │
ℹ Complex selectors are hard to read and override, and break easily when the page structure changes.
ℹ Simplify the selector, for example by giving the element a class and selecting it directly.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
input[type="text"] {}maxPseudoClasses
Section titled “maxPseudoClasses”Default: no limit
The maximum number of pseudo-classes, such as :hover or :first-child, allowed in a
single selector. Pseudo-elements such as ::before don’t count, including the older
single-colon forms :before, :after, :first-line, and :first-letter.
{ "linter": { "rules": { "nursery": { "noExcessiveSelectorComplexity": { "level": "on", "options": { "maxPseudoClasses": 1 } } } } }}Invalid
Section titled “Invalid”li:first-child:hover {}code-block.css:1:1 lint/nursery/noExcessiveSelectorComplexity ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ This selector has too many pseudo-classes: it has 2, but the limit is 1.
> 1 │ li:first-child:hover {}
│ ^^^^^^^^^^^^^^^^^^^^
2 │
ℹ Complex selectors are hard to read and override, and break easily when the page structure changes.
ℹ Simplify the selector, for example by giving the element a class and selecting it directly.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
a:hover::before {}maxUniversals
Section titled “maxUniversals”Default: no limit
The maximum number of universal selectors (*) allowed in a single selector.
{ "linter": { "rules": { "nursery": { "noExcessiveSelectorComplexity": { "level": "on", "options": { "maxUniversals": 1 } } } } }}Invalid
Section titled “Invalid”* > * {}code-block.css:1:1 lint/nursery/noExcessiveSelectorComplexity ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ This selector has too many universal selectors: it has 2, but the limit is 1.
> 1 │ * > * {}
│ ^^^^^
2 │
ℹ Complex selectors are hard to read and override, and break easily when the page structure changes.
ℹ Simplify the selector, for example by giving the element a class and selecting it directly.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
.list > * {}maxCompounds
Section titled “maxCompounds”Default: no limit
The maximum number of compound selectors allowed in a single selector. A compound
selector is a group of selectors written together without spaces or combinators. For
example, nav a.link:hover has two compound selectors: nav and a.link:hover.
{ "linter": { "rules": { "nursery": { "noExcessiveSelectorComplexity": { "level": "on", "options": { "maxCompounds": 2 } } } } }}Invalid
Section titled “Invalid”nav ul a {}code-block.css:1:1 lint/nursery/noExcessiveSelectorComplexity ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ This selector has too many compound selectors: it has 3, but the limit is 2.
> 1 │ nav ul a {}
│ ^^^^^^^^
2 │
ℹ Complex selectors are hard to read and override, and break easily when the page structure changes.
ℹ Simplify the selector, for example by giving the element a class and selecting it directly.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
nav a.link:hover {}maxCombinators
Section titled “maxCombinators”Default: no limit
The maximum number of combinators allowed in a single selector. A combinator is the
symbol between two compound selectors: a space, >, +, ~, or ||.
{ "linter": { "rules": { "nursery": { "noExcessiveSelectorComplexity": { "level": "on", "options": { "maxCombinators": 1 } } } } }}Invalid
Section titled “Invalid”.menu > .item > a {}code-block.css:1:1 lint/nursery/noExcessiveSelectorComplexity ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ This selector has too many combinators: it has 2, but the limit is 1.
> 1 │ .menu > .item > a {}
│ ^^^^^^^^^^^^^^^^^
2 │
ℹ Complex selectors are hard to read and override, and break easily when the page structure changes.
ℹ Simplify the selector, for example by giving the element a class and selecting it directly.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
.menu > .item {}disallowCombinators
Section titled “disallowCombinators”Default: []
Combinators that aren’t allowed. Accepted values are " " (a space, which selects
elements inside another element), ">", "+", "~", and "||".
{ "linter": { "rules": { "nursery": { "noExcessiveSelectorComplexity": { "level": "on", "options": { "disallowCombinators": [ ">" ] } } } } }}Invalid
Section titled “Invalid”.menu > .item {}code-block.css:1:7 lint/nursery/noExcessiveSelectorComplexity ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ The combinator > isn't allowed.
> 1 │ .menu > .item {}
│ ^
2 │
ℹ The rule's configuration disallows this combinator in selectors.
ℹ Rewrite the selector without it, for example by giving the element a class and selecting it directly.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
.menu .item {}disallowPseudoClasses
Section titled “disallowPseudoClasses”Default: []
Pseudo-classes that aren’t allowed, written without the leading colon. Names are compared without regard to letter case.
{ "linter": { "rules": { "nursery": { "noExcessiveSelectorComplexity": { "level": "on", "options": { "disallowPseudoClasses": [ "hover" ] } } } } }}Invalid
Section titled “Invalid”a:not(.active):hover {}code-block.css:1:15 lint/nursery/noExcessiveSelectorComplexity ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ The pseudo-class :hover isn't allowed.
> 1 │ a:not(.active):hover {}
│ ^^^^^^
2 │
ℹ The rule's configuration disallows this pseudo-class in selectors.
ℹ Rewrite the selector without it, for example by giving the element a class and selecting it directly.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
a:not(.active) {}disallowPseudoElements
Section titled “disallowPseudoElements”Default: []
Pseudo-elements that aren’t allowed, written without the leading colons. Names are
compared without regard to letter case. The older single-colon forms :before,
:after, :first-line, and :first-letter are checked as well.
{ "linter": { "rules": { "nursery": { "noExcessiveSelectorComplexity": { "level": "on", "options": { "disallowPseudoElements": [ "before" ] } } } } }}Invalid
Section titled “Invalid”a:before {}code-block.css:1:2 lint/nursery/noExcessiveSelectorComplexity ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ The pseudo-element :before isn't allowed.
> 1 │ a:before {}
│ ^^^^^^^
2 │
ℹ The rule's configuration disallows this pseudo-element in selectors.
ℹ Rewrite the selector without it, for example by giving the element a class and selecting it directly.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
input::placeholder {}disallowAttributes
Section titled “disallowAttributes”Default: []
Attribute names that aren’t allowed in attribute selectors. Names must match exactly, including letter case.
{ "linter": { "rules": { "nursery": { "noExcessiveSelectorComplexity": { "level": "on", "options": { "disallowAttributes": [ "class" ] } } } } }}Invalid
Section titled “Invalid”[class*="button"] {}code-block.css:1:2 lint/nursery/noExcessiveSelectorComplexity ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ The attribute class isn't allowed.
> 1 │ [class*="button"] {}
│ ^^^^^
2 │
ℹ The rule's configuration disallows this attribute in selectors.
ℹ Rewrite the selector without it, for example by giving the element a class and selecting it directly.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
input[type="text"] {}disallowAttributeMatchers
Section titled “disallowAttributeMatchers”Default: []
Operators that aren’t allowed in attribute selectors. Accepted values are "=", "~=",
"|=", "^=", "$=", and "*=".
{ "linter": { "rules": { "nursery": { "noExcessiveSelectorComplexity": { "level": "on", "options": { "disallowAttributeMatchers": [ "*=" ] } } } } }}Invalid
Section titled “Invalid”[class*="button"] {}code-block.css:1:7 lint/nursery/noExcessiveSelectorComplexity ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ The attribute operator *= isn't allowed.
> 1 │ [class*="button"] {}
│ ^^
2 │
ℹ The rule's configuration disallows this attribute operator in selectors.
ℹ Rewrite the selector without it, for example by giving the element a class and selecting it directly.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
[class="button"] {}See Also
Section titled “See Also”- To limit the number of classes in a selector, see
noExcessiveSelectorClasses.
Related links
Section titled “Related links”Copyright (c) 2023-present Biome Developers and Contributors.