DEV Community

Cover image for CSS :is() fun
Caity Opelka
Caity Opelka

Posted on • Edited on

CSS :is() fun

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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 h1s 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;
}
Enter fullscreen mode Exit fullscreen mode

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 h1s 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;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

Now imagine further down in the CSS file, you try to reassign the color of the paragraph text to red.

main p {
    color: red;
}
Enter fullscreen mode Exit fullscreen mode

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.

Sources: MDN

Top comments (7)

Collapse
 
cchana profile image
Charanjit Chana

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!

Collapse
 
imcaity profile image
Caity Opelka • Edited

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!

Collapse
 
cchana profile image
Charanjit Chana

: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 though

Collapse
 
astrit profile image
Astrit

Nice headline you got there and :is() truly nice and fun to use makes life a lot easier.

Collapse
 
astrit profile image
Astrit

BTW Ill steal you this tagline for a tweet with your permission

Collapse
 
imcaity profile image
Caity Opelka

Thanks! Have at it

Collapse
 
facundocorradini profile image
Facundo Corradini

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.