Parent Selectors in CSS

Avatar of Chris Coyier
Chris Coyier on (Updated on )

Let’s be clear here, just in case someone is finding this from a search engine: there are no parent selectors in CSS, not even in CSS3. It is an interesting topic to talk about though, and some fresh talk has surfaced.

Back in 2008, Shaun Inman suggested the syntax:

a < img { border: none; }

[Corrected the following sentence]: In this example, it would select a tags but only if they contained an img tag. (Aside: this would be a weird departure from the typical syntax where the actual elements being selected are on the right, this would be on the left).

Definitely read through the comments on that post, it is a super interesting thread, and contains some pretty signifiant reasons parent selectors don’t exist yet. David Hyatt, a developer on the front-lines of implementing these kinds of things in WebKit, comments that:

With parent selectors it becomes extremely easy to accidentally cause a document-wide grovel. People can and will misuse this selector. Supporting it is giving people a whole lot of rope to hang themselves with.

Jonathan Snook resurfaced this topic and gives us lots of great background on how CSS rendering works. We’ve all heard before that the universal selector is the least efficient CSS selector. Jonathan says if there was a parent selector, that would then easily be the new top dog in inefficient selectors. The argument being that when elements are dynamically added and removed from the page, it may result in the entire document needing to be re-rendered (major memory usage concerns). Jonathan is still optimistic though:

What I’ve described is not technically impossible. In fact, quite the opposite. It just means that we’d have to deal with the performance implications of using such a feature.

Remy Sharp also gets in on the fun, and suggests this syntax:

a img:parent { background: none; }

The key difference being that the :parent syntax would only evaluate a single element, the parentNode available in the DOM for every element. This would be similar to forcing the :has selector to only evaluate children rather than all descendants.

So far everyone is in agreement:

  • There are huge performance concerns
  • Those concerns can be thought of as tradeoffs we should evaluate, not show-stoppers.
  • Want!