Optimize CSS with the :is() Pseudo-Class Selector

When styling aspects of your website, it’s not unusual to need to target numerous similar items at once. Your code can get lengthy, repetitive and complex. Fortunately, the :is() pseudo-class selector introduced in the Selectors Level 4 specification can help simplify it.

Using the :is() Selector

Example 1

A common scenario where you can use :is() is when you want to modify any heading under the same conditions, like when links are inside of headings.

Normally, this is what that selector would need to look like:

h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
    color: red;
}

And to style the links on hover you’d also need:

h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover {
    color: dark-red;
}

The :is() pseudo-class selector simplifies these with the resulting selectors:

:is(h1, h2, h3, h4, h5, h6) a {
    color: red;
}
:is(h1, h2, h3, h4, h5, h6) a:hover {
    color: dark-red;
}

By supplying a group of selectors to match as part of a longer selector, :is() saves repeating common aspects of your longer selector, increasing the readability and maintainability of your code.

Example 2

Another example would be if you needed to style an element differently when it’s inside a few different parent containers. Maybe you want to style your shop’s product images in a unique way when they are used in a few of the layout components you built.

In this scenario, your code may look something like this:

.component-type-one .product img, .component-type-two .product img, component-type-four .product img {
    aspect-ratio: 1.33/1;
}
.component-type-three .product img, .component-type-five .product img {
    aspect-ratio: 1/1.33;
}

With the :is() pseudo-class selector, those can now be written as:

is:( .component-type-one, .component-type-two, .component-type-four ) .product img {
    aspect-ratio: 1.33/1;
}
is:( .component-type-three, .component-type-five ) .product img {
    aspect-ratio: 1/1.33;
}

Then, when you build your sixth and later components, you only need to add those classes to the existing lists, and not write completely new selectors.

:is() Selector Specificity and Forgiveness

When providing a comma-separated list of targets, all items get the specificity value of the most-specific item. This means that a selector written using :is() can have a different specificity than the same selector written without using :is().

In the following example, even though both rules target an item with a class of foo where typically the second matching rule would be blue, since the first rule includes a more specific selector of div.bar the first .foo will result in the element having a red background color.

:is( .foo, div.bar ) {
    background-color: red;
}
.foo {
    background-color: blue;
}

:is() is a forgiving selector. That means that unlike typical CSS selectors where an entire statement is invalid if any part is invalid, an invalid item in your comma-separated list does not break all valid items.

For more details on specificity and selector forgiveness, read our previous post on :has(), which shares the same characteristics.

The CSS pseudo-class :is() is available in all modern browsers so you can start writing your CSS with it today.

For further web development assistance, contact our experts today.

See how Hall can help increase your demand.