← Back to list

CSS :has(): The Game-Changing Selector

CSS :has() — The Parent Selector That Changes Everything

Prateek Sharma · 2026-01-28 07:16 · 0 claps · 2.4 min read
#css #selectors
Open on Medium ↗
Wiki topics: 🌐 · Web Development

CSS :has(): The Game-Changing Selector

CSS :has() — The Parent Selector That Changes Everything

For years, front-end developers have wished for a way to select a parent element based on its children in CSS. We often resorted to JavaScript or overly complex markup to solve this.

Enter **:has(), a CSS relational pseudo-class that finally makes this possible. With :has(), CSS can look inside elements and apply styles conditionally** based on what they contain. This opens up a whole new world of styling possibilities that were previously impossible.

What is :has()?

The :has() pseudo-class matches elements that contain (or are related to) elements inside the parentheses.

Syntax

selector:has(child-selector) {
  property: value;
}

It reads like:

“Select any selector that has a child-selector inside it.

Basic Examples

1. Style a parent <div> if it has an <img>

div:has(img) {
  border: 2px solid green;
}

👉 Any <div> containing an image will get a green border.

2. Highlight a card only if it contains a button

.card:has(button) {
  background: #f9f9f9;
}

👉 Useful for feature cards or product blocks where call-to-action buttons are optional.

3. Active navigation item

nav li:has(a.active) {
  font-weight: bold;
  color: blue;
}

👉 No extra .active class needed on <li>. The parent <li> inherits style when its child <a> is active.

4. Conditional sibling styling

h2:has(+ p) {
  margin-bottom: 0;
}

👉 If an <h2> is immediately followed by a <p>, we remove the bottom margin. A small but powerful touch for better typography.

Real-World Use Cases

1. Forms & Validation

.form-group:has(input:invalid) {
  border: 1px solid red;
  background: #ffeeee;
}

👉 Entire form groups highlight if any contained input is invalid.

2. Media Cards

.card:has(:is(img, video)) {
  border: 2px solid #333;
}

👉 Any card that contains media (image or video) gets a styled border.

3. Accordion or Dropdown States

.accordion:has(.accordion-content[open]) {
  background: #f1f1f1;
}

👉 The accordion container changes appearance when its content is expanded.

4. Shopping Cart Example

.cart:has(.item) {
  border: 2px solid #0073e6;
}
.cart:not(:has(.item)) {
  opacity: 0.6;
}

👉 Cart looks active only if it has items, and visually faded if empty — all with pure CSS.

Combining :has() with Other Pseudo-Classes

The real magic happens when :has() works together with :is(), :not(), or :where().

Example — Active Navigation Highlight

.nav-item:has(> a:is(.active, .current)) {
  background: #0073e6;
  color: white;
}

Example — Exclude Specific Elements

section:has(h2):not(:has(img)) {
  padding: 2rem;
  background: #fafafa;
}

👉 Sections with headings but no images get a neutral background.

Browser Support

  • ✅ Chrome 105+
  • ✅ Safari 15.4+
  • ✅ Edge 105+
  • ⚠️ Firefox — still behind a flag as of 2025

Before using :has() in production, check if your user base relies heavily on Firefox.

Can I Use :has()

Why :has() Matters

  • Less JavaScript: Many DOM-manipulation use cases can now be solved directly in CSS.
  • Cleaner Markup: No need to add redundant parent classes.
  • More Expressive CSS: You can finally write “if/else” style conditions.

It feels like CSS has stepped into the world of logic — without losing its declarative nature.

Final Thoughts

The :has() pseudo-class is a game-changer for CSS. It brings flexibility, reduces reliance on JavaScript, and empowers developers to write smarter, more intuitive styles.

If you haven’t tried it yet, start experimenting with :has() in small UI components like cards, navigation menus, or form validation. Once you see how powerful it is, you’ll never want to go back.


메타데이터
post_id
93e52327cd3c
slug
css-has-the-game-changing-selector-93e52327cd3c
url
https://medium.com/@uxuip29/css-has-the-game-changing-selector-93e52327cd3c
canonical_url
https://medium.com/@uxuip29/css-has-the-game-changing-selector-93e52327cd3c
author_url
https://medium.com/@uxuip29
status
ok
fetched_at
2026-06-24 11:06:28