How to Use New CSS “:is()” for Easy Element Targeting

Read MoreThe new CSS :is() pseudo-class is shaping up to become a great way to target elements, saving on lines and lines of code, and keeping CSS as readable as possible. It is the next stage of the evolution of :matches() and :any(), adding a little extra functionality and increasing how semantic and intuitive the language behind selectors is.In this quick tip we’ll make acquaintance with it. Let’s start by seeing how this pseudo-class, officially referred to in the spec as “matches-any”, is used in application. Then we’ll talk about how it’s replacing both :matches() and :any(), and why it makes more sense to use the word “is” instead.
#CSS:is() selector 🎉the successor to :any() and :matches()sneak peak into our talk, here’s a neat gif I made with XD showing what the :is() selector syntax can do. be excited for Chrome Dev Summit y’all!— Λdam Λrgyle (@argyleink) November 7, 2019

Example Uses of :is()You can probably intuit the functionality of :is() just by looking at it: it’s a means to test if an element is a certain thing, working essentially as a boolean like the if  you’ll find in many programming languages. For example, in its simplest form these two selectors are functionally the same:article {…}:is(article) {…}In both cases the styling will activate if an element is an article.It can also be used to detect multiple types of elements in a single declaration via a comma separated list. For example, again, these two selectors are functionally the same:article, section, aside {…}:is(article, section, aside) {…}By itself this might not seem very interesting–an added complexity if anything–but it becomes especially helpful when used to target child elements. For example, let’s say you wanted to target h1 elements, but only when they are a child of an article, section or aside element. Usually you would need to write:article h1,
section h1,
aside h1 {
font-weight: 900;
}However by instead using is:() this can be compressed to::is(article, section, aside) h1 {
font-weight: 900;
}It really starts to ramp up in efficiency when you have multiple parent and child elements you want to test for. What if, instead of just targeting child h1 elements, as in the above example, you want to target all child heading elements? Without :is(), (and not using classes for the sake of illustration), you would need to write:article h1, article h2, article h3, article h4, article h5, article h6,
section h1, section h2, section h3, section h4, section h5, section h6,
aside h1, aside h2, aside h3, aside h4, aside h5, aside h6, {
font-weight: 900;
}But with :is() instead you only need::is(article, section, aside) :is(h1, h2, h3, h4, h5, h6) {
font-weight: 900;
}Why :is() Replaces :any() and :matches()In previous drafts of the “matches-any” spec this pseudo-class used the name :matches() before subsequently being renamed to :is(). An older selector again is :any(), however unlike :is() or :matches() it doesn’t support complex selectors.The primary reason it makes sense to instead use :is() comes from another boolean style pseudo-class that functions in the inverse way, that being :not(). With this “matches-none” pseudo-class you can apply styling to everything but a collection of selectors.For example, earlier we targeted all the headings that are children of article, section and aside elements. With :not() we can target all the headings that are not children of these elements::not(article, section, aside) :is(h1, h2, h3, h4, h5, h6) {
font-weight: 400;
}It makes good grammatical sense to pair :is() with :not(), hence making the combination logical and intuitive, and this is the primary reason it’s replacing :any() and :matches(). That said, the fact that it’s shorter to type has also been cited as one of the reasons it is an improvement.Current Status and SupportThe :is() “matches-any” pseudo-class is currently at working draft status.You can mostly try it out now in Firefox, Chrome and Safari, however all three browsers are still using the old :any() name, which must be used with vendor prefixes. For Firefox use :-moz-any() and for Chrome and Safari use :-webkit-any(). Chrome and Safari also support :matches().FallbacksYou can also use :any() and :matches() to create fallbacks for :is(). For example, a cross browser set of fallbacks might look like this::-webkit-any(article, section, aside) h1 {
font-weight: 900;

:-moz-any(article, section, aside) h1 {
font-weight: 900;

:matches(article, section, aside) h1 {
font-weight: 900;

:is(article, section, aside) h1 {
font-weight: 900;
}The devs behind PostCSS are also looking at adding the ability to automate the addition of these fallbacks into your code.Wrapping UpThe :is() pseudo-class is going to make it feasible to handle much more complex element targeting than before, using vanilla CSS where previously we would have most likely needed a pre-processor to handle the task. We can all look forward to it coming out of draft status and reaching full browser support.For more information check out the links listed below:Related Links
:is() W3C spec draft

:is() at
MDN Web Docs – :is() (:matches(), :any())

MDN Web Docs – :not()
Learn More About CSS SelectorsCSS
Demystifying CSS Pseudo-Classes (:nth-child vs. :nth-of-type)
Kingsley Silas Chijioke
What is CSS Specificity and How Does it Work?
Kingsley Silas Chijioke
Web Development
The 30 CSS Selectors You Must Memorize
Jeffrey Way

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top