The Lost Feed

🔬Weird Science

What Nobody Tells You About CSS :has() and Parent Selectors

Discover the hidden power of CSS :has(), the 'parent selector' that changes how you style websites. Learn its surprising uses and how it makes your code cleaner.

2 views·6 min read·Jul 20, 2026
Using: Has() as a CSS Parent Selector and much more

CSS has always been powerful, but some things felt impossible. We've wished for a "parent selector" for years, a way to style an element based on what's *inside

  • it. Now, that wish has come true, and it's even more incredible than we imagined.

The :has() pseudo-class is here, and it's not just a parent selector. It's a game-changer that lets you style elements based on their children, their siblings, and so much more. Get ready to rethink how you write CSS.

What Nobody Tells You About CSS :has() and Parent Selectors

For a long time, web developers dreamed of a "parent selector." This would let you style a div if it had, say, an image inside it. Or style a list item if it contained a special link. It seemed like a simple request, but CSS didn't have a way to do it.

Then came :has(). Many people call it the "parent selector," and it certainly does that job well. But calling it *just

  • a parent selector is like calling a smartphone *just

  • a phone. It does so much more, and understanding its full power will change your web projects.

The "Parent Selector"

Myth and Reality

The term "parent selector" is easy to understand, and it's a great way to introduce :has(). If you want to style an element based on its children, :has() is your friend. For example, section:has(h1) would select any <section> element that contains an <h1> heading.

This simple idea unlocks a lot of possibilities. You can finally create styles that react to the content within an element, not just the element itself or its direct ancestors. This makes your CSS much smarter and often reduces the need for JavaScript.

Beyond the Basics: Selecting

Ancestors and Siblings

While styling a parent based on a child is great, :has() goes deeper. It can select an element if it "has" a descendant, no matter how deep. For example, `ul:has(li

a.active)would select a<ul>if any of its<li>children have an<a>tag with the classactive`.

But it's not just about parents and children. :has() can also look at siblings. Imagine you want to style an input field differently if a specific sibling element, like an error message, is present *after

  • it. You can do that with :has().

:has() lets you look forward and backward in your HTML structure, creating styles that react to a wider range of conditions than ever before.

This ability to check for different elements nearby opens up many new styling patterns. It gives you incredible control over your layouts and component designs.

Practical Examples: Making Your Web Pages Smarter

Let's look at some real-world uses for :has(). These examples show how it can simplify your code and create more dynamic user interfaces. You might find yourself deleting lines of JavaScript after learning these tricks.

  • Styling a card based on its content: Imagine a card element. You want it to have a different border if it contains an image. div.card:has(img) { border: 2px solid blue; } This selects any div with the class card that contains an <img> tag.

  • Highlighting a navigation item with an active child: If your navigation has a ul and you want to highlight the whole li when its a tag is active. li:has(a.active) { background-color: yellow; } This helps users see the active section more clearly.

  • Form validation visual cues: You can style an input field's label if the input itself is invalid. label:has(+ input:invalid) { color: red; } This selects a label that is immediately followed by an input that is invalid. This is powerful for user feedback.

These are just a few simple examples. The more you play with :has(), the more *creative solutions

  • you will discover for common styling problems.

Improving

Accessibility and User Experience

Using :has() can lead to better accessibility and a smoother user experience. By making styles more reactive to the state of elements, you can provide clearer visual cues without complex scripting. This means less work for you and a better experience for your visitors.

For instance, you could style a submit button differently when all required fields in a form are filled out. Or you could hide an "empty state" message only when a list actually contains items. These small visual changes add up to a much more polished product.

Dynamic Layouts Without Extra Classes

Before :has(), you often needed to add helper classes to your HTML to achieve conditional styling. For example, card--has-image or form-group--invalid. While these still have their place, :has() lets you achieve many of these effects purely with CSS.

This means cleaner HTML, less code to maintain, and a more semantic structure. Your HTML can focus on its meaning, and your CSS can handle the presentation logic based on that meaning.

Browser

Support and Performance Considerations

When can you start using this amazing feature? Good news: all major modern browsers support :has(). This includes Chrome, Firefox, Safari, Edge, and Opera. So, you can confidently use it in most new projects today.

As for performance, modern browsers are highly optimized. While complex selectors can sometimes be slower, :has() is generally efficient. Browsers have been designed to handle these kinds of checks quickly. Don't worry about it slowing down your site unless you're creating extremely complex and deeply nested :has() rules that run on thousands of elements. For most common uses, the performance impact is negligible.

Tips for

Mastering the :has() Pseudo-Class

To get the most out of :has(), keep a few things in mind.

  1. Start simple: Don't try to solve your most complex problem first. Begin with basic parent selection, then gradually add more complexity.

  2. Combine with other selectors: :has() works wonderfully with other CSS selectors like + (adjacent sibling), ~ (general sibling), and attribute selectors.

  3. Think about your HTML structure: Good HTML structure makes using :has() much easier and more effective. If your HTML is messy, :has() might become too complicated.

  4. Test thoroughly: Always test your :has() rules across different browsers and devices to ensure they work as expected.

Remember that :has() is a powerful tool. Like any powerful tool, it's best used thoughtfully. It can simplify your code, but it can also make it harder to read if overused or used incorrectly.

The

Future of CSS is Here

The introduction of :has() is a big moment for CSS. It shows that the language is still growing and adapting to the needs of modern web development. It closes a long-standing gap in CSS capabilities and opens the door for even more expressive styling.

This pseudo-class empowers developers to write cleaner, more semantic, and more maintainable stylesheets. It reduces the reliance on JavaScript for styling tasks, making websites potentially faster and more robust. Embrace :has() and discover a whole new world of possibilities in your CSS.

It's time to experiment, build, and create web experiences that were once only dreams. The future of CSS is exciting, and :has() is a huge part of it.

How does this make you feel?

Comments

0/2000

Loading comments...