The :has
pseudo-class in CSS is a powerful selector introduced in CSS Selectors Level 4. This property allows developers to apply styles to an element based on the presence of its descendants or related elements, effectively enabling “parent” selectors, which was a long-requested feature in CSS.
What is the :has Property?
The :has
property is a relational pseudo-class that matches elements containing elements that meet certain criteria. It’s particularly useful for styling an element if it contains specific child elements or if certain conditions within its subtree are met.
Syntax
The basic syntax of the :has
pseudo-class is:
element:has(selector) {
/* styles */
}
In this syntax, element
represents the parent element, and selector
represents the child or descendant elements being checked.
Practical Examples
Let’s explore some practical examples to understand how the :has
property works.
Example 1: Highlighting a Parent Element Based on a Child Element
Suppose we want to highlight a div
element if it contains an img
element. Here’s how we can do it:
<div>
<p>This div contains an image.</p>
<img src="https://via.placeholder.com/150" alt="Placeholder Image">
</div>
<div>
<p>This div does not contain an image.</p>
</div>
div:has(img) {
border: 2px solid green;
padding: 10px;
}
Example 2: Styling a List Item’s Parent Based on the Child Element
If we want to style a ul
element differently when it contains a li
element with a specific class, we can use the :has
property:
<ul>
<li>Item 1</li>
<li class="highlight">Item 2</li>
<li>Item 3</li>
</ul>
<ul>
<li>Item A</li>
<li>Item B</li>
<li>Item C</li>
</ul>
ul:has(li.highlight) {
background-color: lightyellow;
padding: 10px;
}
Example 3: Form Validation Styles
We can also use the :has
pseudo-class for form validation. For instance, to style an input
element’s parent div
if the input is invalid:
<form>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" id="email" required>
</div>
<button type="submit">Submit</button>
</form>
.form-group:has(input:invalid) {
border: 2px solid red;
padding: 10px;
}
Comparison with JavaScript
Traditionally, achieving similar effects to the :has
pseudo-class required using JavaScript. For example, checking for the presence of a child element and then applying styles dynamically. While JavaScript provides flexibility, using CSS for such tasks can be more efficient and reduce the complexity of your code.
Here’s how you can achieve the same result of Example #1 with vanilla javascript:
document.addEventListener("DOMContentLoaded", function() {
const divs = document.querySelectorAll('div');
divs.forEach(div => {
if (div.querySelector('img')) {
div.style.border = '2px solid green';
div.style.padding = '10px';
}
});
});
While the
:has
pseudo-class adds powerful capabilities to CSS, it is essential to consider performance. Using complex selectors can impact rendering performance, especially on pages with many elements. Always test your styles to ensure they do not introduce significant performance issues.
Browser Support
As of now, the :has
pseudo-class is not yet supported in all browsers. It is essential to check current browser compatibility and consider using polyfills or fallbacks for unsupported browsers.
Conclusion
The :has
pseudo-class in CSS is a game-changer for developers, enabling more complex and dynamic styling possibilities. By understanding and using this powerful selector, you can create more interactive and visually appealing web pages with ease. Keep an eye on browser support and start experimenting with :has
to take your CSS skills to the next level.