The Power of :has() in CSS
Publikováno: 30.3.2024
Hey all you wonderful developers out there! In this post we are going to explore the use of :has()
in your next web project. :has()
is relatively newish but has gained popularity in the front end community by delivering control …
The Power of :has() in CSS originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.
Hey all you wonderful developers out there! In this post we are going to explore the use of :has()
in your next web project. :has()
is relatively newish but has gained popularity in the front end community by delivering control over various elements in your UI. Let’s take a look at what the pseudo class is and how we can utilize it.
Syntax
The :has()
CSS pseudo-class helps style an element if any of the things we’re searching for inside it are found and accounted for. It’s like saying, “If there’s something specific inside this box, then style the box this way AND only this way.”
:has(<direct-selector>) {
/* ... */
}
The Styling Problem
In years past we had no way of styling a parent element based on a direct child of that parent with CSS or an element based on another element. In the chance we had to do that, we would need to use some JavaScript and toggle classes on/off based on the structure of the HTML. :has()
solved that problem.
Let’s say that you have a heading level 1 element (h1
) that is the title of a post or something of that nature on a blog list page, and then you have a heading level 2 (h2
) that directly follows it. This h2 could be a sub-heading for the post. If that h2
is present, important, and directly after the h1
, you might want to make that h1 stand out. Before you would have had to write a JS function.
Old School Way – JavaScript
const h1Elements = document.querySelectorAll('h1');
h1Elements.forEach((h1) => {
const h2Sibling = h1.nextElementSibling;
if (h2Sibling && h2Sibling.tagName.toLowerCase() === 'h2') {
h1.classList.add('highlight-content');
}
});
This JS function is looking for all the h1’s that have a h2
proceeding it, and applying a class of highlight-content to make the h1
stand out as an important article.
New and improved with modern day CSS coming in hot! The capabilities of what we can do in the browser have come a long way. We now can take advantage of CSS to do things that we traditionally would have to do with JavaScript, not everything, but some things.
New School Way – CSS
h1:has(+ h2) {
color: blue;
}
Throw Some :has() On It!
Now you can use :has()
to achieve the same thing that the JS function did. This CSS is checking for any h1 and using the sibling combinator checking for an h2 that immediately follows it, and adds the color of blue to the text. Below are a couple use cases of when :has()
can come in handy.
:has Selector Example 1
HTML
<h1>Lorem, ipsum dolor.</h1>
<h2>Lorem ipsum dolor sit amet.</h2>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eius, odio voluptatibus est vero iste ad?</p>
<h1>Lorem, ipsum dolor.</h1>
<h2>Lorem ipsum dolor sit amet.</h2>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eius, odio voluptatibus est vero iste ad?</p>
<h1>This is a test</h1>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eius, odio voluptatibus est vero iste ad?</p>
CSS
h1:has(+ h2) {
color: blue;
}
:has Selector Example 2
A lot of times we as workers on the web are manipulating or working with images. We could be using tools that Cloudinary provides to make use of various transformations on our images, but usually we want to add drop shadows, border-radii, and captions (not to be confused with alternative text in an alt attribute).
The example below is using :has()
to see if a figure or image has a figcaption element and if it does, it applies some background and a border radius to make the image stand out.
HTML
<section>
<figure>
<img src="https://placedog.net/500/280" alt="My aunt sally's dog is a golden retreiver." />
<figcaption>My Aunt Sally's Doggo</figcaption>
</figure>
</section>
CSS
figure:has(figcaption) {
background: #c3baba;
padding: 0.6rem;
max-width: 50%;
border-radius: 5px;
}
Can I :has()
that?
You can see that :has()
has great support across modern browsers.
This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.
Desktop
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
105 | 121 | No | 105 | 15.4 |
Mobile / Tablet
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
122 | 123 | 122 | 15.4 |
:has()
in the Community!
I reached out to my network on Twitter to see how my peers were using :has()
in their day-to-day work and this is what they had to say about it.
svg:has(> #Mail) {
stroke-width: 1;
}
It is great to see how community members are using modern CSS to solve real world problems, and also a shout out to Abbey using it for accessibility reasons!
Things to Keep in Mind
There are a few key points to keep in mind when using :has()
Bullet points referenced from MDN.
- The pseudo-class takes on specificity of the most specific selector in its argument
- If the
:has()
pseudo-class itself is not supported in a browser, the entire selector block will fail unless:has()
is in a forgiving selector list, such as in:is()
and:where()
- The
:has()
pseudo-class cannot be nested within another:has()
- Pseudo-elements are also not valid selectors within
:has()
and pseudo-elements are not valid anchors for:has()
Conclusion
Harnessing the power of CSS, including advanced features like the :has()
pseudo-class, empowers us to craft exceptional web experiences. CSS’s strengths lie in its cascade and specificity…the best part, allowing us to leverage its full potential. By embracing the capabilities of CSS, we can drive web design and development forward, unlocking new possibilities and creating groundbreaking user interfaces.
Links:
- https://ishadeed.com/article/css-has-parent-selector/
- https://css-tricks.com/almanac/selectors/h/has/
- https://developer.chrome.com/blog/has-m105/#forms
- https://css-tricks.com/the-css-has-selector/
The Power of :has() in CSS originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.