This content originally appeared on Go Make Things and was authored by Go Make Things
Last week, I finally had a reason to use the newish :is()
CSS pseudo-class, and wow is it glorious!
Today, I want to show you how it can dramatically reduce selector complexity. Let’s dig in!
What :is()
does
The :is()
pseudo-class accepts a comma-separated list of selectors, and can be used to group them together.
For example, these two selector strings do the same thing…
h1, h2, h3, h4, h5, h6 {
font-weight: bold;
}
:is(h1, h2, h3, h4, h5, h6) {
font-weight: bold;
}
You’re probably look at this and thinking…
Why the fuck would you ever need that!?
And as-written, you’d be right! It’s pointless.
Where :is()
really shines is when you have complex and repeated sets of nested selectors.
Easier nesting selectors with :is()
I recently worked on a website where I had several different .bg-*
utility classes for creating sections with colored backgrounds.
A few of them (but not all of them) have darker background colors that require white text instead of black. This site also featured heading elements that used a different color than the standard text color.
The original CSS looked like this…
.bg-primary-dark,
.bg-secondary,
.bg-secondary-dark,
.bg-primary-dark h1,
.bg-primary-dark h2,
.bg-primary-dark h3,
.bg-primary-dark h4,
.bg-primary-dark h5,
.bg-primary-dark h6,
.bg-secondary h1,
.bg-secondary h2,
.bg-secondary h3,
.bg-secondary h4,
.bg-secondary h5,
.bg-secondary-dark h6,
.bg-secondary-dark h1,
.bg-secondary-dark h2,
.bg-secondary-dark h3,
.bg-secondary-dark h4,
.bg-secondary-dark h5,
.bg-secondary-dark h6,
.bg-primary-dark a:not(.btn),
.bg-secondary a:not(.btn),
.bg-secondary-dark a:not(.btn) {
color: #ffffff;
}
.bg-primary-dark figcaption,
.bg-secondary figcaption,
.bg-secondary-dark figcaption {
color: #f7f7f7;
}
.bg-primary-dark a:not(.btn):hover,
.bg-secondary a:not(.btn):hover,
.bg-secondary-dark a:not(.btn):hover {
color: #d9d9d9;
}
This is… a lot!
Using the :is()
pseudo-class, I was able to rewrite it like this…
:is(.bg-primary-dark, .bg-secondary, .bg-secondary-dark),
:is(.bg-primary-dark, .bg-secondary, .bg-secondary-dark) :is(h1, h2, h3, h4, h5, h6, a:not(.btn)) {
color: var(--color-white);
}
:is(.bg-primary-dark, .bg-secondary, .bg-secondary-dark) figcaption {
color: var(--color-gray-light)
}
:is(.bg-primary-dark, .bg-secondary, .bg-secondary-dark) a:not(.btn):hover {
color: var(--color-gray-medium-dark);
}
As you can see, it’s far easier to write, and far easier to read and reason about as well!
Another way you could do this
Technically, you could achieve the same result using CSS nesting.
.bg-primary-dark,
.bg-secondary,
.bg-secondary-dark {
h1, h2, h3, h4, h5, h6,
a:not(.btn) {
color: #ffffff;
}
figcaption {
color: #f7f7f7;
}
a:not(.btn):hover {
color: #d9d9d9;
}
}
I personally find the nesting easier to read, largely because I’ve spent most of my career writing Sass-flavored CSS.
But that’s mostly a matter of taste/personal opinion.
The more compelling argument for using :is()
is that it has far better browser compatibility compared to CSS nesting.
A little “gotcha” with :is()
and specificity
In his article on CSS nesting, my buddy Killian Valkhof points out a potentially specificity gotcha with :is()
…
… remember that
:is()
takes on the highest specificity of the selectors in it.
I don’t think it’s a deal-breaker, but if you’re using lots of nested CSS selectors:
- Maybe you shouldn’t be.
- You might hit some unintentional UI behavior because of specificity.
Despite these potential issues, I’m really excited to finally have tried :is()
and to have it in my toolkit!
Like this? A Lean Web Club membership is the best way to support my work and help me create more free content.
This content originally appeared on Go Make Things and was authored by Go Make Things

Go Make Things | Sciencx (2025-03-18T14:30:00+00:00) Reducing CSS complexity with the :is() pseudo-class. Retrieved from https://www.scien.cx/2025/03/18/reducing-css-complexity-with-the-is-pseudo-class/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.