By Viviana Menzel on Saturday, 20 December 2025
Category: December

CSS Shorts: :has()

The CSS :has() pseudo-class is often called the long-awaited “parent selector” in CSS, enabling developers to style elements based on their children or siblings.

What is :has()?

CSS selectors traditionally flow downward: you could select children, descendants, or siblings, but not the parent itself. The :has() pseudo-class, introduced in the CSS Selectors Level 4 specification, changes this behavior. It allows developers to select an element if it contains, or is followed by specific elements, making CSS far more flexible and powerful. The has() pseudo-class is baseline (works across the latest browser versions) since December 2023.

The :has() pseudo-class is a relational selector. It matches an element if the relative selector passed inside its parentheses finds at least one match anchored to that element. In other words, it lets you style a parent or sibling element based on the presence of certain children or neighbours.

Examples

Styling the parent:

div:has(p) {
  background-color: lavender;
}

This rule applies a lavender background to any <div> that contains a <p> element.

<figure>
    <img src="images/thumb.jpg" alt="" />
    <figcaption>Three swallows</figcaption>
</figure>
<figure>
    <img src="images/thumb.jpg" alt="Three swallows" />
</figure>
img {
    border-radius: 8px;
}
figure:has(figcaption) {
    padding: .5rem;
    background-color: #fff;
    box-shadow: 0 3px 10px 0 rgba(0, 0, 0, 0.2);
    border-radius: 8px;
}

If the figure element contains a caption (figcaption) it becomes a padding, a white background and a box-shadow. A figure without caption displays only the image with rounded corners.

.grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 1rem;
    margin-bottom: 1rem;
}
.grid:has(> :last-child:nth-child(2)) {
    grid-template-columns: 1fr 1fr;
}

In this example you have a grid with three columns (it can be a blog layout or the articles module). If you publish only two articles, the grid will still display three columns. Using :has() you can query the number of items inside the grid and change the number of columns.

Styling depending on the sibling

h2:has(+ p) {
    border-block-end: 2px solid crimson;
}

This rule styles all <h2> elements which are immediately followed by a <p>.

Combine with :not()

div:has(:not(h2, h3)) {
 background-color: lightblue;
}

Any <div> that contains anything that is not an <h2> or an <h3> becomes a light blue background.

div:not(:has(.featured)) {
 background-color: #ff7e5f;
}

This rule styles any <div> that doesn’t contain an element with the class .featured.

Conclusion

:has() is a very powerful pseudo-class that brings your CSS styling into a new level. For more explanations and examples, please check the links below.

Further readings:

:has() 

:has() | CSS-Tricks 

CSS :has() Interactive Guide

Exploring the :has() Pseudo-class in CSS

Leave Comments