CSS 3 Selectors

John Resig has published a long and very interesting article about CSS 3 Selectors. Being the original author/editor of that spec, I feel I have to answer to his points.

First John sees these selectors from an HTML point of view. I remind the reader that Selectors are not designed specifically for HTML. We had XML in mind when I edited the spec.

Second, when he says "What's fascinating is that no one has ever, ever, requested that these features be added back in. They have virtually zero real-world use and applicability", I think John should think twice before being harsh with the CSS Working Group and the XSL Working Group. Most of these selectors were added to the spec - or taken from the an old XSL draft - after we provided uses cases. Furthermore, most of these selectors are not implemented by IE and not yet by Firefox. Why the hell do you want people to care about them ? There's not a single book about them because the spec is not a REC yet ! Let me give another very concrete example : when Håkon Lie proposed :target, it was only for navigation ; nobody ever expected what I did with it : tabs with a demo!!!

So we have here selectors that are not implemented yet or not interoperably and Web designers don't use them. How surprising !!! In CSS, we have some features here to serve some typographic local constraints, because we saw a menu in a restaurant nicely designed and we needed a new feature to be able to make it in CSS. Serves a very little community of users. That community will NEVER show up in any stat. Is that a reason to drop the feature ? You don't see a wide community of users for a given selector ? Is that a reason to drop it ? CERTAINLY NOT.

On the selectors themselves, here are my comments:

  • E:root - very very useful if you consider scoped stylesheets
  • E:empty - very useful for inline editors so they can present differently an element if it's empty
  • E:lang(fr) - yeah, there are only a few multilingual blogs around... I have plenty of them in my RSS agregator, and my own blog is multilingual tagged with lang. Want to see only french content ? *:not(:lang(fr)) { display: none }
  • E:nth-of-type(n) - very sueful to present financial tabular data where odd rows are grey and even rows white for instance
  • E:nth-last-child(n) - similar to the previous one but when you want the last row to be always grey
  • E:nth-last-of-type(n) - idem
  • E:first-of-type - some online newspapers show the first paragraph of their prose in a bigger font, that's #content > p:first-of-type { font-size: larger }
  • E:last-of-type - wonderful to put generated content after the last paragraph of a prose for instance
  • E:only-of-type - I have at least one test case : to change the rendering of a list item if it's alone in its list parent
  • E:only-child - when you're inline-editing : dl > dd:only-child { /* special rules */ }
  • E ~ F - we used a ~ because the combinators we don't have an unlimited set of available combinators. It's only in one direction LIKE EVERYTHING in CSS selectors. You cannot select an element based on its children, you cannot select an element based on its successors
  • E + F - I agree this one is less interesting than the previous one but I use it from time to time, in particular when styling XUL or tag soup coming from an uncontrolled source.
  • E[foo~="bar"] - .class does NOT EXIST for XML because the class attribute is not a cross-dialect generic attribute. So we need this one to make class happen in XML.
  • E[hreflang|="en"] - Oh you english speaker, you should leave a little bit the en-GB and en-US-centric web :-) I know a lot of blogs and sites using this to show the user the target of the link is not in the originating site's language...
About selectors' speed, you seem to forget BROWSERS are not the only environments implementing selectors. Prince for instance has a BATCH processor to print books from HTML and CSS. Speed still matters, but less than in a browser. Again, you made a very common mistake in our world, you read this spec with an HTML-only browser-only eye.


1. On Tuesday 12 February 2008, 14:49 by Marcin Jaworski

You should also notice that John Resig has been writing about usage of these selectors in jQuery JavaScript library. John's mistake was that he was trying to negate usefulness of mentioned selectors in CSS styling of the documents by pointing that they were not very useful for people using them in scripts.

I also would want to point out that the number of sites (59) he took into consideration when creating those statistics is too small to make such assumptions. These are only sites which are using jQuery but there are other JS libraries which are capable of using CSS3 selectors to select elements in scripts.

2. On Tuesday 12 February 2008, 16:05 by Joe Clark

E + F you need for p + p { text-indent: 1em } giving only a paragraph following a paragraph an indent.

3. On Tuesday 12 February 2008, 18:10 by Adam


I think that John makes some very useful points, that are worth taking into account. The most important one, which he does not explicitly state is that CSS should take into account the programming uses for selectors.

I think that the CSS WG would benefit from examining how selectors are being used in the wild and leveraging that.

I also have a pet peeve with a statement you made:

> It's only in one direction LIKE EVERYTHING in CSS selectors.

I've never understood this limitation. Forms are a good example of where this makes for tortured mark-up & JavaScript. I'd kill to be able to wite:

div.field:where(input.required) {
//Style for required fields
div.optionGroup div.group {
div.optionGroup:where(input.option:checked) div.group {

Now you might argue that behaviour belongs in JavaScript, but we already know that Selectors are an integral part of JavaScript development. I suggest that it would be well used.

4. On Wednesday 13 February 2008, 09:45 by Jörn Zaefferer

Maybe adoption of CSS3 would be much better if it had been specifically designed for HTML and browsers.

Adding another spec on top for non-browser enviroments or XML should be possible then, shouldn't it?

5. On Monday 18 February 2008, 14:10 by Rijk

I can follow Daniel's reasoning, except for the :nth-* selectors. Only for the 'odd' and 'even' special cases I can think of some obious usecases. For styling only - no surprise that there is little interest in interacting with every odd row in a table :)

The + selector is useful when you try to write your markup as semantically 'pure' as possible. Though it is not always practical to work that way: you sometimes need to change the stylesheet after changing your document structure a bit.

6. On Monday 18 February 2008, 19:04 by Alan Gresley

Hi Daniel

That is just crazy what John is suggesting. He has no concept of future web development when these selectors are common place. I would like to create (X)THTML code without a single class or id in the code apart from those used with script. I have added my own comments on his blog and elsewhere.

Alan :-)

7. On Tuesday 19 February 2008, 21:19 by Jörn Zaefferer

@Alan: Completely relying on the structure of a document instead of classes has quite a cost. Adding a single element somewhere in the document may require tons of changes in the stylesheet when the selector didn't just use a class. Same applies for scripts, where it maybe even worth to fix the issue.

8. On Wednesday 20 February 2008, 03:07 by Alejandro Mut

Of course these selectors are not widely used, only because most mainstream browsers do not support them (IE, hello)! Don't think that dropping them before giving developers the chance to fool around with them is a good idea.

The CSS-only tabs is a good example of what may be acheived if developers start playing with the "new" selectors to solve "old" problems (don't like the jump-to-anchor effect when you click on the tabs, though).