Using :has() pseudo-class to style elements based on their children
Most developers are familiar with CSS selectors that target elements based on their attributes, classes, or IDs. However, there's a lesser-known pseudo-class called :has()
that allows you to style elements based on the presence of specific children.
What is :has()
?
The :has()
pseudo-class is a part of the CSS Selectors Level 4 specification. It takes a selector as an argument and matches elements that have at least one child that matches the provided selector.
Example code
/* Style a container element if it has a child with the class "error" */
.container:has(.error) {
background-color: #f2dede; /* light red background */
border: 1px solid #a94442; /* red border */
}
/* HTML structure */
<div class="container">
<p>This is a normal message.</p>
</div>
<div class="container">
<p class="error">This is an error message.</p>
</div>
1. HTML Structure
You can represent the HTML structure using a simple tree diagram:
HTML Structure
└── div.container
├── p (This is a normal message.)
└── div.container
└── p.error (This is an error message.)
2. CSS Styles
Next, you can illustrate how the CSS applies to the HTML elements. You can use arrows or lines to show which styles apply to which elements.
CSS Styles
┌───────────────────────────────────────────────────────────────────┐
│ .container:has(.error) { │
│ background-color: #f2dede; /* light red background */ │
│ border: 1px solid #a94442; /* red border */ │
│ } │
└───────────────────────────────────────────────────────────────────┘
↑
│
┌────────────┴────────────┐
│ Applies to: │
│ div.container │
│ (with .error child) │
└─────────────────────────┘
3. Final Visualization
You can combine the HTML structure and CSS styles into one visual representation. You might use color coding to show the styles applied:
HTML Structure with Styles
┌───────────────────────────────────────────────────────────────────┐
│ div.container (styled) │
│ ├── p (This is a normal message.) │
│ └── p.error (This is an error message.) │
│ └── (Background: light red, Border: red) │
└───────────────────────────────────────────────────────────────────┘
In this example, the .container
element will receive the styles (light red background and red border) only if it has a child element with the class .error
.
How it works
When the browser encounters the .container:has(.error)
selector, it checks if the .container
element has any children that match the .error
selector. If it finds at least one matching child, it applies the styles to the .container
element.
Use cases
This trick can be useful in various scenarios, such as:
Error handling: Style a container element differently if it contains an error message.
Validation: Highlight a form field if it contains an invalid input.
Content-aware layouts: Adjust the layout of a container element based on the presence of specific content.
Browser Support
The :has()
pseudo-class is supported in modern browsers, including Chrome, Firefox, Safari, and Edge.
Keep in mind that this is a Level 4 selector, so older browsers might not support it. Make sure to check the browser support before using this trick in production.