Selectors That Depend on Layout

Avatar of Chris Coyier
Chris Coyier on

“Why the heck don’t we have ::first-column?”

I heard someone ask that the other day and it’s a valid question. I’d even take that question further by asking about ::nth-column() or whatever else relates to CSS columns. We have stuff like ::first-letter and ::first-line. Why not others?

There are many notable things missing from the “nth” crowd. Seven years ago, I wrote “A Call for ::nth-everything” and it included clear use cases like, perhaps, selecting the first two lines of a paragraph.

I don’t know all the technical details of it all, but I know there are some fairly decent reasons why we don’t have all of these in CSS. Part of it is the difficulty of getting it specced (e.g. words and characters get tricky across written languages) and part of it is the difficulty of implementing them. What I just found out is that there is a FAQ document that explains!

So, why don’t we have ::first-column? Because it’s a “selector that depends on layout”:

This falls into a class of problems that unlikely to be solvable in CSS: selectors in general, and pseudo classes in particular, cannot depend on layout, because otherwise they could be used to modify layout in a way that made them no longer match, which would modify the layout back to where it was, so they match again, and we get stuck in an infinite loop of contradictions.

For a simple example:

:stuck { position: static; }

Now what?

Some of the changes web developers might want to apply with a :stuck pseudo class may be safe and not trigger such loops, but selectors are a generic mechanism, and would enable this kind of contradictions.

So even though many of the problem people are trying to address using such pseudo classes are legitimate, selectors are unlikely to be the answer.

What we’ve got are infinite loops that are basically the problem (but read the FAQ — it goes into great detail about the nuance of it). In a related way, the same reason we don’t have element queries in CSS.

It’s a little tricky to think about because even stuff like ::first-line are riddled with paradoxes. Say you use it to increase the font-size. That means fewer characters fit on the line, so the characters that originally matched are now pushed down and don’t match anymore. Seems a bit loopy, but that’s been sorted out. Plus, classics like :hover potentially causing jitter. The document talks about these things in clear terms. It’s not all cut and dry!

The whole FAQ is a fascinating read and covers much more than this situation.

Direct Link →