:has() Has Landed


:has() has been the last entry in my recently published list of major (new) CSS features. And I concluded:

Game changer! Bigger than all of the above.

And yet, there has been no occurance of this powerful selector on this site. Fair enough, it’s been only a couple of weeks since we got cross-browser support.

A dash of :has()

Lately, I’ve been adding a dash of :has() to my pull requests at work whenever possible. So it would only be matter of time until the same is true on my personal site. Last night, while I added support for <details> and <summary>[1], it finally happened.

When I looked at the commit, I found my first personal use of :has() to be rather unusual, which inspired this blog post.

Let me write down what I ended up with verbatim:

li:has(> details:only-child) {
	list-style-type: none;
li:has(> details:only-child) summary {
	list-style-position: outside;

This essentially removes the bullet in every list item that contains a <details> element (and nothing else), and turns the <summary> triangle marker (i.e. its expanded/collapsed indicator) into the list item’s indicator.

While this may be a bit too much of an edge case to end up in somebody’s CSS Reset, I found it cool enough to write about it, because it works without any additional styles.[2]. In other words, it can be thrown on top of browsers’ bare user agent styles, which is exactly what I did in the accompanying CodePen.


  1. Another first on this site. While <details> and <summary> play an important role on one of my subdomains, my blog managed to get by without them, that is, until I published the note »Seemingly Bookmarked«. ↩︎
  2. list-style-position: outside puts the marker outside of the focus ring, so in reality you may want to tweak that too. But you get the idea. ↩︎