CSS has evolved a lot over the years. It introduces many new powerful tools that make lives easier. From these tools, today I have picked three of them. We’ll see how :is(), :has(), and :where() pseudo-classes help simplify code, make it more readable, and reduce repetition.
This article teaches you, what, how, and why of :is(), :where(), and :has() pseudo-classes. You’ll see how we can use these pseudo-classes to design our website by writing less and more optimized code, which can be an excellent practice in software development.
As we will explore pseudo-classes, here is a basic overview in one sentence. In CSS pseudo-class is a rule that applies to an element based on a certain condition or state. Follow this link to learn more about pseudo-classes.
What problem are we resolving?
When designing our website using CSS (cascading stylesheet), one thing we all face is code repetition.
For Example:
.card .title, .card .body-content, .card .footer-action {
...
}
In this example, I have a .card selector that is repeated for each of its child selectors. But simultaneously, you will also see that the same styling is applied to them.
This is how group selector works normally in CSS by separating each selector with a comma. This code works fine, but my concern here is to avoid repeating and not organized well.
Another issue that we face here is a CSS specificity issue. By using code like that and too much repetition, sometimes we forget what styling is used where and on what condition. This is where these pseudo-classes play an important role.
Let’s see each pseudo-class one by one to understand their purpose.
Explaining :is() pseudo-class
:is() pseudo-class lets you select multiple elements that share the common styles, without repeating the same code. It simplifies selectors by combining them into a single block, reducing redundancy. It takes a list of selectors as an argument and applies styles to all elements that match any of the selectors within that list.
.card :is(.title, .body-content, .footer-action) {
...
}
I have used the above example, and you’ll see how easy it is to reduce repetition in our CSS code by grouping with :is() pseudo-class. It keeps code clean and efficient.
The above example shows we provide .title, .body-content, and .footer-action as an argument to :is() pseudo-class. Before :is() parent container .card is defined to keep its children’s style separate from other code. This is how :is() applies the same styles on all the arguments that match its list.
:is() pseudo-class is widely used in all major browsers, below image from caniuse.com shows the detailed overview for different versions of browsers:
...
Explaining :where() pseudo-class
The :where() pseudo-class is very similar to :is(). We can group multiple selectors to reduce repetition in our code. It takes selectors as an argument. The major difference between :is() and :where() pseudo-class is that, :where() has zero specificity. This means it’s helpful when you want to style elements without adding extra weight to your CSS selector.
Style defined with :where() pseudo-class can be easily overridden. It means :where() does not add extra specificity in its selectors, and style inside :where() pseudo-class is based on selector’s own specificity.
The one good use-case for using :where() pseudo-class is to define the base style for multiple elements and you don’t want that style to affect any more specific rules that may override it later.
This way :where() allows you to apply styles without making your CSS too opinionated about which rules should win in a conflict.
/* Applying a default style */
:where(h1, p, a) {
color: red;
font-size: 20px;
}
/* More specific style */
a {
color: blue;
font-size: 16px;
}
In the above example, h1, p and a tags are provided as an argument to :where() pseudo-class for base styling. After that a tag which is used as a standalone tag with its styling can easily override the style defined in :where().
Like :is(), :where() is also supported in almost all major browsers. See an image below from caniuse.com to check supported browser versions:
Explaining :has() pseudo-class
:has() is a parent selector. This means it allows you to select a parent element based on the children it contains. This a a huge deal because CSS didn’t allow this kind of behavior before. You can also say that :has() as the if statement of CSS because it fulfills the conditional need.
Let’s say you want to style a div only if it contains an img. This was not possible with traditional CSS but :has() made it possible.
<!-- Card with Image -->
<div class="card">
<img src="https://placeholderjs.com/300x300" />
<h1>Card With Image</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque, accusantium.</p>
</div>
<!-- Card without Image -->
<div class="card">
<h1>Card With Image</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque, accusantium.</p>
<a href="#">Call to Action</a>
</div>
.card:has(a) {
background-color: #e6e6e6;
}
.card:has(img) {
background-color: #979759;
}
In this example, you see I have created two div elements with the same .card class, in CSS by using :has() pseudo-class. By using the same .card with :has() pseudo-class, two conditions are given with different styling that you can able to see in the image output.
:has() is also supported in almost all major browsers. See an image below from caniuse.com to check supported browser versions:
Conclusion
As new features are introduced in CSS, the more power it gains, and allows writing code more readable, efficient, and optimized code. You have learned :is(), :where() and :has() pseudo-classes in this article, and you see how useful they are. These pseudo-classes make our job much easier, they can be easily maintained, and the code is optimized.
This article is to show you how powerful these features are, and we’re one step closer of using these features in our project. I highly suggest you use features like these to increase your productivity.
This post is originally posted at programmingly.dev. Read full article by following this link: write less CSS by using :is(), :where(), :has() pseudo-classes