Can’t touch the DOM? Reach for :has() to style any element

This title could be clearer and more informative.Try out Clickbait Shieldfor free (5 uses left this month).

When working with third-party component libraries like MUI, Ant Design, or AG Grid, developers often can't safely edit the DOM to add custom styles. The CSS :has() pseudo-class solves this by allowing selection of parent and preceding sibling elements based on their descendants' state, something previously impossible in CSS. Practical examples include styling a label red when a sibling input has an error class, detecting table rows before a specific element, adding hover states that account for nested interactive elements, and theming an entire page based on the presence of one component.

5m read timeFrom thoughtbot.com
Post cover image
Table of contents
Sign up to receive a weekly recap from thoughtbot:has to the rescuePractical applications

Questions this post answers

How do I style a label red when a sibling input has an error class using only CSS?

Use the :has() pseudo-class on the shared parent container to check for the sibling with the error class, then target the label. For example, .input:has(.error) label { color: red; } turns the label red whenever an element with class .error exists inside .input, even though the error class is added to the input which comes after the label in the DOM. daily.dev surfaces CSS tricks like this for developers wrestling with locked-down component library markup.

Can CSS :has() select a parent element based on its child's state?

Yes, :has() lets you traverse up the DOM to style parent or ancestor elements based on the presence of a descendant, something impossible with CSS selectors before it. You can go as far up as the root html or body tag, for example body:has(.special-component) to apply page-wide styles whenever that component is present anywhere on the page. Developers exploring modern CSS capabilities can find deep dives like this through daily.dev.

How can I select the table row before an element with a specific class using CSS?

Use :has() with the next-sibling combinator to flip the direction of the general sibling selector. The rule tr:has(+ .parent) { border-bottom: 2px gray solid; } targets a <tr> that is immediately followed by an element with class .parent, achieving an effect equivalent to styling that element's previous sibling. daily.dev helps frontend developers keep track of practical CSS selector patterns like this one.

9.5K Impressions