After skimming over some lines of CSS recently, I realized that I had read over a line and understood it without ever having seen it before. I had just come across the :is()
pseudo-class function for the first time, and it looked something like this:
header :is(h1, a) {
color: green;
font-family: sans-serif;
}
It's easy to understand that the above code targets the color and font of any h1
or a
tags inside of the header element. Another way to write the above rule is as follows:
header h1,
header a {
color: green;
font-family: sans-serif;
}
It may not seem like it's that much less to write, but imagine if you were targeting more than two or three elements. The code could get very long and repetitive without the use of :is()
. Writing less code typically leads to having less bugs but that's not the only advantage to using this pseudo-class.
If you have a long chain of selectors and one of them is invalid, that one error invalidates the entire CSS rule. The browser just throws it out completely.
header h1,
header :a {
color: green;
font-family: sans-serif;
}
Using the example above, let's say that you accidentally put a colon in front of the anchor tag. Now the entire rule is invalid. Neither the h1
s or the links will be able to access this rule. On the other hand, if this were written using the :is()
pseudo-class, any other selectors that are not invalid will still be affected by the rule.
header :is(h1, :a) {
color: green;
font-family: sans-serif;
}
In the example above, although the anchor tag is invalid, the browser will still use the rule on the h1 tag. Only the invalid selector is ignored by the browser with the use of the :is()
pseudo-class.
You can also reverse the logic. In the previous examples, we targeted h1
s and anchors within the header element. Another way to use :is()
is to target the functionality of a specific selector in many elements. Below, we are giving all links within the main
, .title
, and p
tag a color of purple on hover.
:is(main, .title, p) a:hover {
color: purple;
}
One thing to note is that it does follow a level of specificity. Let's target anything with a class of .title
or a paragraph tag in the main element and give them a color of orange.
main :is(.title, p) {
color: orange;
}
Now imagine further down in the CSS file, you try to reassign the color of the paragraph text to red.
main p {
color: red;
}
You might be surprised to find out that the color remains orange. This is because the color was originally tied to whatever selector had the highest rank of specificity when it was passed to the :is()
pseudo-class. In this case, .title
had the highest specificity, which then ties the color of p
to the color of .title
, resulting in the paragraph text remaining red. If the .title
class had not been called in the previous :is()
pseudo-class, the color of the paragraph text would indeed have updated to the color of the most recent rule because the paragraph tag became the selector with the highest specificity.
This mini-dive into the :is()
was the result of coming across a snippet of code that sparked my curiosity. Stay curious! There's always more to learn.
Top comments (7)
Thanks for sharing, I've never really looked into using
:is()
but can see that it's really useful. I was intrigued by the bit about invalid selectors::is(h1, :a)
I tested it out and it works great in Chrome, but not in Safari (macOS): codepen.io/cchana/pen/NWbmXdJ
But that's not a big deal, same as before you just need to make sure they selectors are correct but thinking about it some more, this is a fantastic way to simplify your CSS! Fairly well supported, definitely something I'm going to look at making use of in the future!
Definitely has its pros and cons, but it's worth tinkering. Also check out :not(), which does the opposite and excludes the selectors passed to it. Cheers!
:not()
is awesome, I use it all the time! It took me a while to adjust my writing style for CSS to get into the habit vs using something like:last-child
instead thoughNice headline you got there and :is() truly nice and fun to use makes life a lot easier.
BTW Ill steal you this tagline for a tweet with your permission
Thanks! Have at it
Nice writeup! While I appreciate the simpler syntax of :is() compared to the traditional comma-separated list, I'm concerned about the specificity trap it sets up.
Can't think of any scenario where this behaviour is useful, and it will certainly cause unexpected results everywhere.