Skip to main content

selector-no-unmatchable

Disallow unmatchable selectors.

label:enabled {}
/** ↑
* Selectors like this */

Unmatchable selectors are valid, but can never match anything.

This rule flags selectors that:

  • pair a pseudo-class with elements it never matches, e.g. label:enabled
  • pair pseudo-classes that never match the same element, e.g. :any-link:checked
  • combine a pseudo-element with tree-structural pseudo-classes, e.g. ::before:first-child
  • contain pseudo-elements within :is() or :where(), which cannot represent them, e.g. :is(::before)
  • contain the nesting selector (&) where it cannot represent its pseudo-element ancestor rules
  • select around the shadow host in ways its tree does not allow, e.g. a :host and ::slotted(:host)

This rule resolves nested selectors according to the CSS Nesting specification.

warning

This rule is only appropriate for CSS. You should not turn it on for CSS-like languages, such as SCSS or Less.

This rule supports up to 3 message arguments: the selector, its resolved form when nesting is involved, and the reason it is unmatchable.

Options

true

{
"selector-no-unmatchable": true
}

The following patterns are considered problems:

label:checked {}
::before:first-child {}
:is(::before) {}
a::before {
.foo:hover & {}
}
a :host {}

The following patterns are not considered problems:

input:checked {}
a::before {}
.foo:hover a::before {}
:host a {}