The CSS :has()
pseudo-class, often referred to as the "parent selector," represents a significant advancement in CSS. It allows you to select an element based on the presence, or even the state, of its descendants. This means you can style a parent element or a preceding sibling element by checking for specific elements or conditions within it, which was previously impossible with CSS alone.
Example 1: Basic Parent Selection
/* Selects an article element that contains a p element */
article:has(p) {
border: 2px solid steelblue;
padding: 1rem;
}
Explanation
This code targets any <article>
element that has at least one <p>
element as a descendant. It then applies a border and padding to that <article>
, visually highlighting it.
Example 2: Styling Based on a Specific Child
/* Selects a div that has an h2 with the class .title */
div:has(h2.title) {
background-color: #f0f8ff;
}
Explanation
Here, the selector targets a <div>
only if it contains an <h2>
element that also has a class of .title
. This allows for conditional styling of a container based on its specific content.
Example 3: Form Validation Styling
/* Selects a form-group that contains an invalid input */
.form-group:has(input:invalid) {
background-color: #ffebee;
border-left: 5px solid #c62828;
}
Explanation
This example showcases how :has()
can be used for dynamic form styling. It selects the parent .form-group
and applies a distinct style if any <input>
element within it is in an :invalid
state.
Example 4: Sibling Selection with :has()
/* Selects an h1 that is followed by a p element */
h1:has(+ p) {
margin-bottom: 0.5rem;
}
Explanation
The :has()
pseudo-class can be combined with sibling combinators. This code selects an <h1>
element only if it is immediately followed by a <p>
element and reduces its bottom margin.
Example 5: Multiple Conditions
/* Selects a figure that contains both an image and a figcaption */
figure:has(img):has(figcaption) {
text-align: center;
}
Explanation
You can chain :has()
selectors to check for multiple conditions. This rule applies styles to a <figure>
element only if it contains both an <img>
and a <figcaption>
element.
Example 6: Targeting Empty Elements
/* Selects a div that contains an empty p element */
div:has(p:empty) {
display: none;
}
Explanation
This snippet demonstrates how to select a parent based on the state of a child. It targets any <div>
that contains an empty <p>
element and hides the <div>
from view.
Example 7: Conditional Layout Changes
/* Selects a card container and changes its layout if it has more than 3 items */
.card-container:has(.card:nth-child(n+4)) {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1rem;
}
Explanation
This advanced example makes the layout of a .card-container
responsive to the number of .card
elements it contains. If there are four or more cards, it switches to a two-column grid layout.