CSS :is() and :where()
The :is() and :where() pseudo-class functions allow you to group selectors, reducing repetition and making CSS more readable. They function similarly but have one key difference regarding specificity.
1. Grouping Selectors
Instead of writing the same selector multiple times with different variations, you can group them.
Without :is():
header p,
main p,
footer p {
color: red;
}
With :is():
:is(header, main, footer) p {
color: red;
}
This is equivalent to the expanded version above.
2. The Difference: Specificity
The main difference between :is() and :where() is how they affect the specificity of the selector.
:is()
The specificity of the :is() pseudo-class is equal to the most specific selector in its argument list.
/* Specificity: (0, 1, 0, 1) - ID wins */
:is(#id, .class, tag) {
color: blue;
}
Even if the element matches .class, the rule carries the weight of #id.
:where()
The specificity of the :where() pseudo-class is always zero (0, 0, 0, 0). It does not add any weight to the selector.
/* Specificity: (0, 0, 0, 0) */
:where(#id, .class, tag) {
color: green;
}
3. Use Cases
Simplifying Selectors
Both are great for reducing code duplication.
/* Complex selector */
article h1, article h2, article h3,
section h1, section h2, section h3 {
margin-bottom: 1em;
}
/* Simplified */
:is(article, section) :is(h1, h2, h3) {
margin-bottom: 1em;
}
Resetting Styles (:where)
Because :where() has zero specificity, it is perfect for CSS resets or default library styles. It allows developers to easily override the styles without needing high specificity or !important.
/* Library default */
:where(.btn) {
background-color: gray; /* Specificity 0 */
}
/* User override */
.btn {
background-color: blue; /* Specificity 0, 1, 0 - Wins! */
}
Forgiving Selector Lists
Both :is() and :where() use a "forgiving selector list". In standard CSS, if one selector in a comma-separated list is invalid, the entire rule is ignored. Inside :is() or :where(), the invalid selector is ignored, but the valid ones still work.
/* If :unsupported is invalid, the whole rule fails in standard CSS */
:unsupported, h1 { color: red; }
/* With :is(), h1 still gets styled */
:is(:unsupported, h1) { color: red; }
programming/css/css programming/css/selectors programming/css/specificity