Saturday, February 24, 2024

How to Use the :has() Selector in CSS 2024 technical tricks

 For most of the history of CSS, selectors have been limited to targeting elements based on their parents in the DOM tree. Consider this HTML structure:

The :has() selector is a relational pseudo-class in CSS that selects an element based on its relationship with other elements. It can be used to select an element if it contains another element that matches a given selector.


<div>

    <p>Paragraph 1</p>

<div>

<main>

    <div>

    <p>Paragraph 2</p>

    </div>

 <main>


 Applying styles to paragraph 2 in CSS is trivial, as it can be targeted by the parent <main> node.

main p {

    color: blue;

}


 This will style Paragraph 2 but not Paragraph 1, as the second paragraph is contained inside the <main> element.


What has not historically been simple however, was styling the <main> node based on the presence of the <p> tag below it.

<main>

    Don't Style This

</main>

<main>

    <p>Style This</p>

</main>


By looking upwards in the DOM tree, there was no way to apply styles to just the second <main> element and not the first (without uses classes or IDs of course).

Introducing the :has() Selector

At its core, the :has() selector is a relational pseudo-class. This means it allows you to select an element based on its relationship with other elements. Specifically, it selects an element if it contains another element that matches a given selector.

In the above example, we can now do the following:

main:has(p) {

    color: red;

}


This opens up numerous possibilities for styling your web pages more efficiently and with less code.

Example 1 – Highlighting Articles with Images

Consider a webpage that displays a list of articles, each enclosed in an <article> tag. If we want to highlight articles that contain images, the :has() selector offers a straightforward solution:

article:has(img) {

  border: 2px solid red;

}

 



This CSS rule applies a blue border around any <article> tag that contains an <img> element, visually distinguishing articles with images from those without.

Example 2 - Styling Navigation Menus with Sub-Menus

Here is another example. In this example, the :has() selector is being used to add a :before() pseudo element to any menu item that has sub menus – that is any <li> element that contains a child element with the class .sub-menu.

.main-menu > li:has(.sub-menu):before {
  content: "▼";
  margin-left: 5px;
  font-size: 0.75em;
}







Browser Support

As of March 2024, the :has() selector is supported by approximately 92% of web browsers globally, including all the most common modern browsers such as the latest versions of Chrome, Firefox, Safari and Edge. For unsupported browsers, consider using feature detection libraries like Modernizr to apply alternative styles.

It's also a good idea to design your CSS to degrade gracefully, ensuring that your web pages remain at least functional and visually acceptable in browsers that do not support the :has() selector.

Ready to Use Today

The :has() selector offers a new level of flexibility and power in CSS, enabling you to write cleaner, more efficient stylesheets. By selecting elements based on their content, the :has() selector simplifies many common styling challenges, from highlighting articles with images to styling responsive layouts.

As browser support continues to grow, 2024 is the perfect year to begin incorporating the :has() selector into your CSS.




Previous Post
Next Post

post written by:

0 Comments: