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.