Group Selectors and Control Specificity
':is()' and ':where()'
`:is()` groups selectors and takes the highest specificity inside. `:where()` does the same with zero specificity.
What you'll learn
- Use `:is()` to keep CSS DRY
- Use `:where()` for low-priority defaults
:is() and :where() are similar — they both match like a comma
list of selectors. They differ in specificity.
:is() — Same as Comma List
:is(h1, h2, h3) {
font-family: "Inter", sans-serif;
}
/* equivalent to */
h1, h2, h3 {
font-family: "Inter", sans-serif;
} The point of :is() is combinations:
:is(header, footer, nav) :is(h2, h3) {
margin-top: 0;
} This is header h2, header h3, footer h2, footer h3, nav h2, nav h3
— in one line.
Specificity
:is() takes the specificity of its MOST specific argument.
:is(.btn, #main) { ... } /* specificity = (1, 0, 0), from #main */ :where() — Zero Specificity
:where() matches the same as :is() but contributes zero
specificity:
:where(h1, h2, h3) {
margin-top: 1rem; /* easy to override */
}
h2 {
margin-top: 2rem; /* wins — even with the same specificity */
} Used in CSS resets and base layers — establish defaults that any real rule can override without a fight.
Practical Pattern
/* Generic typography defaults — easy to override */
:where(p, li, dd) {
line-height: 1.6;
}
/* Component-level — beats defaults without specificity tricks */
.lead p {
line-height: 1.4;
} Up Next
Modern color functions — color-mix, OKLCH, contrast.