CSS pseudo-class - :has()
CSS :has() pseudo-class represents an element based on whether it has a child element that matches a certain selector.
Syntax
:has(<relative-selector-list>) {
/* ... */
}
The :has() pseudo-class is not supported by Firefox browser.
Ponits to remember
When a browser doesn't support the :has() pseudo-class, the entire selector block will only work if :has() is used inside an :is() or :where() selector.
You can't use a :has() selector inside another :has()selector because many pseudo-elements exist based on how their parent elements are styled. Allowing you to select these pseudo-elements with :has() can cause cyclic querying.
Pseudo-elements cannot be used as selectors or anchors within the :has() pseudo-class.
CSS :has() - Sibling Combinator
Here is an example of how to use :has() function to select all h2 elements that are immediately followed by an h3 element −
<html>
<head>
<style>
div {
background-color: pink;
}
h2:has(+ h3) {
margin: 0 0 50px 0;
}
</style>
</head>
<body>
<p>You can see it adds bottom margin to h2 elements immediately followed by an h3 element.</p>
<div>
<h2>Tutorialspoint</h2>
<h3>CSS Pseudo-class - :has()</h3>
<p>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old.</p>
</div>
</body>
</html>
CSS :has() - With :is() Pseudo-class
CSS selector :is(h1, h2, h3) selects all h1, h2, and h3 elements. The :has() pseudo-class then selects any of these elements that have an h2, h3, or h5 element as their next sibling, as shown below −
<html>
<head>
<style>
div {
background-color: pink;
}
:is(h1, h2, h3):has(+ :is(h2, h3, h5)) {
margin-bottom: 50px ;
}
</style>
</head>
<body>
<p>You can see it adds bottom margin to h2 elements immediately followed by an h3 element and h3 element followed by immediately h4.</p>
<div>
<h2>Tutorialspoint</h2>
<h3>CSS Pseudo-class :has()</h3>
<h5>with :is() Pseudo-class</h5>
<p>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old.</p>
</div>
</body>
</html>
CSS :has() - Logical Operations
The :has(video, audio) selector checks if either a video or audio element is present within the element.
The :has(video):has(audio) selector checks wheter element contains both video or audio element.
Here is an example of how to use :has() pseudo-class to add a red border and a 50% width to the body element if it contains a video or audio element −
<html>
<head>
<style>
video {
width: 50%;
margin: 50px;
}
body:has(video, audio) {
border: 3px solid red;
}
</style>
</head>
<body>
<video controls src="images/boat_video.mp4"></video>
</body>
</html>
Regular Expressions and :has() Analogy
CSS :has() selectors and regular expressions with lookahead assertions share a similarity in that they enable you to target elements (or strings) based on a specific pattern, all without actually choosing the element (or string) that matches that pattern.
| Features | Description |
|---|---|
| Positive lookahead (?=pattern) | CSS selector and the regular expression abc(?=xyz) both allow you to select an element based on the presence of another element immediately after it, without actually selecting the other element itself. |
| Negative lookahead (?!pattern) | CSS selector .abc:has(+ :not(.xyz)) is like the regular expression abc(?!xyz). Both select .abc only if it is not followed by .xyz. |