DEV Community

Cover image for CSS :has() Pseudo-Class: A Powerful Selector for Dynamic Styling
ZeeshanAli-0704
ZeeshanAli-0704

Posted on

CSS :has() Pseudo-Class: A Powerful Selector for Dynamic Styling

CSS is continuously evolving to enable developers to build dynamic, intuitive, and visually appealing web pages with ease. One such enhancement is the :has() pseudo-class, introduced in modern CSS. This pseudo-class brings a parent-aware selection capability, allowing you to apply styles conditionally based on the presence or state of child or sibling elements.

This article explains the :has() pseudo-class with an example to demonstrate its flexibility and power.

What is the :has() Pseudo-Class?

The :has() pseudo-class is often referred to as a "parent selector" because it allows you to style an element based on its children, siblings, or descendants.

selector:has(selectorList)

Enter fullscreen mode Exit fullscreen mode
  • selector is the main element to which the rule applies.
  • selectorList is the condition, which can include children, siblings, or other elements related to the main element.

Key Features

  • Parent-awareness: Styles are applied to an element based on its descendants or siblings.
  • Flexible conditions: Works with combinators like +, ~, and > for sibling and child relationships.
  • Improved interactivity: Useful for creating dynamic layouts or effects without relying on JavaScript.

Practical Example: Using :has() to Style a Box Based on Its Sibling

body {
  font-family: sans-serif;
}

.box {
  width: 50px;
  height: 40px;
  background-color: red;
  margin: 5px;
}

.border {
  border: 2px solid black;
}

.circle {
  width: 40px;
  height: 40px;
  background-color: blue;
  border-radius: 25px;
}

/* Highlighting boxes that are followed by a circle */
.box:has(+ .circle) {
  width: 80px;
  height: 80px;
}

Enter fullscreen mode Exit fullscreen mode
<!DOCTYPE html>
<html>
  <head>
    <title>CSS :has() Example</title>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="./styles.css" />
  </head>
  <body>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box border"></div>
    <div class="circle"></div>
    <div class="box"></div>
  </body>
</html>


Enter fullscreen mode Exit fullscreen mode

Explanation

Basic Styles
The .box class defines small red rectangles with a margin.
The .circle class creates blue circular elements.

Dynamic Sizing Using :has():
The rule .box:has(+ .circle) applies styles to any .box element that is immediately followed by a .circle.
This rule changes the dimensions of such .box elements to 80px by 80px, making them stand out.

Visual Output

Initially, the boxes are uniform in size.
The .box element immediately preceding a .circle grows larger due to the :has() rule.

Image description

Use Cases for :has()

The :has() pseudo-class is versatile and can be applied in numerous scenarios:

1. Interactive Layouts

Style a parent element based on the presence of a specific child or sibling element, e.g., highlighting a card if it contains a button.

.card:has(button) {
  border: 2px solid green;
}
Enter fullscreen mode Exit fullscreen mode

2. Dynamic Navigation Menus

Apply styles to a parent <li> if it contains a dropdown menu.

li:has(ul) {
  font-weight: bold;
}
Enter fullscreen mode Exit fullscreen mode

3. Form Validation

Highlight invalid input fields based on sibling or parent elements.

.form-group:has(input:invalid) {
  border-color: red;
}
Enter fullscreen mode Exit fullscreen mode

4. Custom Sibling Relationships

Style an element based on its adjacent sibling.

h1:has(+ p) {
  margin-bottom: 10px;
}
Enter fullscreen mode Exit fullscreen mode

Advantages of :has()

  1. Improves Readability:

    • Reduces the need for complex JavaScript to detect and manipulate the DOM.
  2. Boosts Performance:

    • Lightweight and efficient compared to JavaScript solutions for similar effects.
  3. Simplifies CSS:

    • Enables declarative styling for complex relationships, minimizing extra classes or attributes.

Browser Support

As of now, the :has() pseudo-class is supported by most modern browsers, including:

  • Chrome: 105+
  • Edge: 105+
  • Safari: 15.4+
  • Firefox: Support is under consideration.

For older browsers, you may need a fallback or polyfill.


Conclusion

The :has() pseudo-class is a game-changer in modern CSS, bringing the long-awaited parent selector capability. With its ability to conditionally style elements based on their relationships, it simplifies CSS code, enhances dynamic styling, and reduces reliance on JavaScript for DOM manipulation.

Explore the :has() pseudo-class in your projects and unlock new possibilities for creative and efficient web designs!

Top comments (0)