The CSS :has() pseudo-class, aka Parent Selector Bookmark

Just in time for the holidays, the CSS :has() pseudo-class has arrived in the Safari technology preview 137, enabled by default. Cool beans! Everybody is pretty excited about this announcement, because it's basically been “…parent selector is not possible…” for a long time and now we‘re like “Cool, the impossible parent selector has actually arrived in CSSland!”. Who would have thought.

Personally I'm excited about :has(), which I believe will change the way I (or we?) will write CSS in the future.

/* Selects any <a> element, as long as it directly contains an <img> element */
a:has(> img) {
  border: 1px solid pink;
}
The result of the above line of CSS used on the homepage of this site (Safari TP 137)

While being able to select parent elements is a rather big deal, I‘m as much excited about the possibilities to check for certain element combinations and the different styling options thereof. I really like this example of :has() for form labels and nested/unnested input elements, a typical use case with text fields, checkboxes or radio buttons:

/* <input> element nested within the <label> */
label:has(> input) {
  …
}

/* the <label> element followed by <input> */
label:has(+ input) {
  …
}

In combination with :is() which I wrote about before, it‘ll make a nice selector team for future CSS.

It‘s been some time that something new has arrived where I thought that it will change the approach of writing CSS. Maybe the last big thing that did that were media queries in 2010? Anyways, it‘ll still be a little while until :has() will have good browser support, but implementations happen much faster these days, so let‘s see when it will become a daily tool of choice.

More information and examples on Bram.us and MDN.

CSS has pseudo-class browser support table