Limit and disallow the CSS selectors.
The CSS selectors are used to target HTML elements so that styles can be applied to them. Selectors can target HTML element tags, IDs, classes, or attributes applied to elements. Selectors can use simple syntax, such as targeting only IDs, classes, or HTML tags, or more complex syntax by combining classes, IDs, attributes, pseudo-classes, pseudo-elements and combinators to match specific elements or groups of elements.
It is a good practice to refrain from using complex selectors to improve maintainability and readability of code, reduce specificity issues, enhance performance, prevent bugs etc.
This rule limits the use of descendant selectors and disallows certain selectors or combinators to prevent overly complex CSS selectors.
This rule accepts an option object with the following properties:
maxIds(default:Infinity) - Specify the number ofIDs can be used in a selector.maxClasses(default: -Infinity) - Specify the number ofclasses can be used in a selector.maxTypes(default:Infinity) - Specify the number oftypes can be used in a selector.maxAttributes(default:Infinity) - Specify the number ofattributes can be used in a selector.maxPseudoClasses(default:Infinity) - Specify the number ofpseudo-classes can be used in a selector.maxUniversals(default:Infinity) - Specify the number ofuniversals can be used in a selector.maxCompounds(default:Infinity) - Specify the number ofcompounds can be used in a selector.maxCombinators(default:Infinity) - Specify the number ofcombinators can be used in a selector.disallowCombinators(default:[]) - Specify an array ofcombinators that are not allowed to be used.disallowPseudoClasses(default:[]) - Specify an array ofpseudo-classes that are not allowed to be used.disallowPseudoElements(default:[]) - Specify an array ofpseudo-elements that are not allowed to be used.disallowAttributes(default:[]) - Specify an array ofattributes that are not allowed to be used.disallowAttributeMatchers(default:[]) - Specify an array ofattribute-matcherss oroperators that are not allowed to be used.
Examples of incorrect code with { maxIds: 1 }:
/* eslint css/selector-complexity: ["error", { maxIds: 1 }] */
#foo #bar {
}
#foo > #bar {
}Examples of correct code with { maxIds: 1 }:
/* eslint css/selector-complexity: ["error", { maxIds: 1 }] */
#foo {
}
#foo,
#bar {
}
#foo:not(#bar) {
}Examples of incorrect code with { maxClasses: 2 }:
/* eslint css/selector-complexity: ["error", { maxClasses: 2 }] */
.foo .bar .baz {
}
.foo > .bar > .baz {
}
a.foo a.bar .baz {
}Examples of correct code with { maxClasses: 2 }:
/* eslint css/selector-complexity: ["error", { maxClasses: 2 }] */
.foo .bar {
}
.foo .bar,
.baz {
}
a.foo a.bar {
}Examples of incorrect code with { maxTypes: 2 }:
/* eslint css/selector-complexity: ["error", { maxTypes: 2 }] */
ul li a {
}
div.foo p a {
}Examples of correct code with { maxTypes: 2 }:
/* eslint css/selector-complexity: ["error", { maxTypes: 2 }] */
li a {
}
li.foo a {
}
button img:not(img.foo) {
}Examples of incorrect code with { maxAttributes: 1 }:
/* eslint css/selector-complexity: ["error", { maxAttributes: 1 }] */
[name="foo"][type="text"] {
}
input:not([name="bar"][disabled]) {
}Examples of correct code with { maxAttributes: 1 }:
/* eslint css/selector-complexity: ["error", { maxAttributes: 1 }] */
[name="foo"] {
}
[type="number"] {
}Examples of incorrect code with { maxPseudoClasses: 1 }:
/* eslint css/selector-complexity: ["error", { maxPseudoClasses: 1 }] */
button:hover + a:visited {
}
.foo:first-child:hover {
}Examples of correct code with { maxPseudoClasses: 1 }:
/* eslint css/selector-complexity: ["error", { maxPseudoClasses: 1 }] */
button:hover + a {
}
li:nth-child(2) a {
}Examples of incorrect code with { maxUniversals: 1 }:
/* eslint css/selector-complexity: ["error", { maxUniversals: 1 }] */
* * {
}Examples of correct code with { maxUniversals: 1 }:
/* eslint css/selector-complexity: ["error", { maxUniversals: 1 }] */
* {
}Examples of incorrect code with { maxCompounds: 2 }:
/* eslint css/selector-complexity: ["error", { maxCompounds: 2 }] */
div p.foo span {
}
.foo #bar > a {
}Examples of correct code with { maxCompounds: 2 }:
/* eslint css/selector-complexity: ["error", { maxCompounds: 2 }] */
p.foo span {
}
#bar a,
button {
}Examples of incorrect code with { maxCombinators: 1 }:
/* eslint css/selector-complexity: ["error", { maxCombinators: 1 }] */
.foo > .bar > .baz {
}
.foo + .bar > a {
}Examples of correct code with { maxCombinators: 1 }:
/* eslint css/selector-complexity: ["error", { maxCombinators: 1 }] */
.foo + .bar {
}
.foo ~ p {
}Examples of incorrect code with { disallowCombinators: [">"] }:
/* eslint css/selector-complexity: ["error", { disallowCombinators: [">"] }] */
.foo > .bar {
}
.foo + .bar > a {
}Examples of correct code with { disallowCombinators: [">"] }:
/* eslint css/selector-complexity: ["error", { disallowCombinators: [">"] }] */
.foo + .bar {
}
.foo ~ p {
}Examples of incorrect code with { disallowPseudoClasses: ["hover"] }:
/* eslint css/selector-complexity: ["error", { disallowPseudoClasses: ["hover"] }] */
button:hover {
}
a:not(.foo):hover {
}Examples of correct code with { disallowPseudoClasses: ["hover"] }:
/* eslint css/selector-complexity: ["error", { disallowPseudoClasses: ["hover"] }] */
ul li:nth-child(2) {
}
a:not(.foo) {
}Examples of incorrect code with { disallowPseudoElements: ["marker"] }:
/* eslint css/selector-complexity: ["error", { disallowPseudoElements: ["marker"] }] */
li::marker {
}Examples of correct code with { disallowPseudoElements: ["marker"] }:
/* eslint css/selector-complexity: ["error", { disallowPseudoElements: ["marker"] }] */
input::placeholder {
}Examples of incorrect code with { disallowAttributes: ["class", "alt"] }:
/* eslint css/selector-complexity: ["error", { disallowAttributes: ["class", "alt"] }] */
[class*="foo"] {
}
img[alt="foo"] {
}Examples of correct code with { disallowAttributes: ["class", "alt"] }:
/* eslint css/selector-complexity: ["error", { disallowAttributes: ["class", "alt"] }] */
input[type="text"] {
}
img[src$=".foo"] {
}Examples of incorrect code with { disallowAttributeMatchers: ["*=", "^="] }:
/* eslint css/selector-complexity: ["error", { disallowAttributeMatchers: ["*=", "^="] }] */
[class*="foo"] {
}
img[alt^="foo"] {
}Examples of correct code with { disallowAttributeMatchers: ["*=", "^="] }:
/* eslint css/selector-complexity: ["error", { disallowAttributeMatchers: ["*=", "^="] }] */
input[class="foo"] {
}
img[alt="foo-bar"] {
}If you aren't concerned with the complexity of the selectors, then you can safely disable this rule.
- selector-max-id
- selector-max-class
- selector-max-type
- selector-max-attribute
- selector-max-pseudo-class
- selector-max-universal
- selector-max-compound-selectors
- selector-max-combinators
- selector-combinator-disallowed-list
- selector-pseudo-class-disallowed-list
- selector-pseudo-element-disallowed-list
- selector-attribute-name-disallowed-list
- selector-attribute-operator-disallowed-list