
Using the CSS :has Pseudo‑Class

The :has CSS parent selector is a relatively new and less well‑known upcoming feature of CSS4 that allows you to select a parent element based on whether it has a specific child or children. Parent selectors as a concept are themselves fairly new (and not for want or need within the development community!).
Using :has, we can resolve a number of common front‑end scenarios, such as when you want to style a container based on the contents of one of its child elements. However, it is important to understand the limitations and ideal use cases of this selector before using it in your own projects.
The biggest limitation here is going to be that the :has selector is currently only part of the working draft for CSS4 selectors, so as you might imagine, browser support is fairly limited and syntax/implementation are still likely to change as the specs mature. The Can I Use reads fairly bleakly at present; essentially unless your entire userbase is on very recent versions of WebKit‑based browsers (Chrome, Safari, or Edge), then you're going to have to find an alternative solution, especially if any of them use Firefox...
Microsoft Edge is a surprise amongst those browsers that are compatible, but perhaps less of a surprise given that EdgeHTML is supposed to be fully compatible with the Webkit Layout Engine.
Using :has
With the more stark compatibility issues out of the way, let's talk about actually using this relational pseudo‑class.
Usage should be very familiar; simply include the :has function followed by the child selector you want to match. For example:
div:has(p) { margin-bottom: 1rem;}What this will do is match any div with a p child, and set the bottom margin to 1rem. This falls back to more generic CSS selectors, so in the example above, both of these parent divs will match:
<!-- This div will match the selector above --><div> <p>Lorem ipsum dollar</p></div><!-- This div will also match the selector above --><div> <article> <p>Lorem ipsum dollar</p> </article></div><!-- This div will also match the selector above --><div> <!-- ..and so will this one --> <div> <p>Lorem ipsum dollar</p> </div></div>You can of course use more complex selectors like child selectors (>). For example:
div:has(> p) { margin-bottom: 1rem;}This will only match divs that have an immediate p child:
<!-- This div will match the selector above --><div> <p>Lorem ipsum dollar</p></div><!-- This div will not match the selector above --><div> <article> <p>Lorem ipsum dollar</p> </article></div>Any normal combination of CSS selector will work within :has, which makes it incredibly powerful.
What you can also do is chain multiple :has selectors together (in the same way you can with pseudo‑classes), which can create more explicit matches. For example, you could select a div element that has both a p element and a img element as children like this:
div:has(p):has(img) { padding: 10rem;}You can also comma‑separate selectors, so the same can be achieved like this:
div:has(p, img) { padding: 10rem;}The Wrap‑Up
To summarise, if you aren't put off by the current level of browser support, then :has is a very powerful feature that can help you to create more complex and dynamic styles for your website, and write more elegant CSS.
It is ‑ however ‑ important to understand its limitations and use it only in appropriate scenarios. At the moment, :has is very performance‑intensive (as it works backwards against the traditional CSS cascade), so you might be better off avoiding it on larger or more complex projects.
Categories:
Related Articles

Spread Syntax in JavaScript (...). Spread Syntax in JavaScript (

Parent Selectors in CSS and Sass. Parent Selectors in CSS and Sass

::Before and ::after Pseudo‑Elements in CSS. ::beforeand::afterPseudo‑Elements in CSS
Single or Double Colons in CSS Pseudo‑Elements (:before vs. ::before). Single or Double Colons in CSS Pseudo‑Elements (
:beforevs.::before)
Understanding the :hover Pseudo‑Class in CSS. Understanding the
:hoverPseudo‑Class in CSS
Practical Use Cases for JavaScript Set and Map. Practical Use Cases for JavaScript
SetandMap
Tagged Template Literals in JavaScript. Tagged Template Literals in JavaScript

Commenting in Front‑End Languages. Commenting in Front‑End Languages

Testing Vue Components with Vue Test Utils. Testing Vue Components with Vue Test Utils

Angular Change Detection: How It Works and How to Optimise It. Angular Change Detection: How It Works and How to Optimise It

Understanding Tail call Optimisation in JavaScript. Understanding Tail call Optimisation in JavaScript

Optimising Vue.js Performance with Lazy Loading and Code Splitting. Optimising Vue.js Performance with Lazy Loading and Code Splitting