The CSS Corner: CSS3 Selectors

CSS3 Selectors enable complex styling of webpages using simpler CSS and less script than previously possible. As we demoed back in November, and updated in March and May with the IE9 Platform Preview Builds, IE9 includes full support for CSS3 selectors. This is a feature which web developers requested and we are excited to fulfill this need.

  • E:root

  • E:nth-child(n)

  • E:nth-last-child(n)

  • E:nth-of-type(n)

  • E:nth-last-of-type(n)

  • E:last-child

  • E:first-of-type

  • E:last-of-type

  • E:only-child

  • E:only-of-type

  • E:only-child

  • E:only-of-type

  • E:empty

  • E:target

  • E:enabled

  • E:disabled

  • E:checked

  • E:indeterminate

  • E:not(s)

  • E::selection

Our goal is to enable new selectors in your webpages in a way that lets the same markup work across browsers. A nice side effect of this work is better results in test suites that measure selectors support. IE9 now passes 100% of test cases on, 100% of the W3C CSS3 Selectors Test Suite, and Acid3 tests 34 through 37 and 39 through 44.

Nth-child and other structural pseudo-classes

Nth-child and other structural pseudo-class selectors allow you to style elements based on some structural information about how they fit in the DOM tree without requiring that you label the elements in any manner. Nth-child selectors are especially useful if you want to maintain styling even as the structure of your page changes.

One of the best use cases for nth-child selectors is to alternate the background color on table rows, for example like this:

Here is a table where the background color
of each row alternates between
light blue and
dark blue.

To style this table without using nth-child selectors, one common technique is to label each row in the markup and then assign a style to each class of rows:

<tr class=”odd> <td>row1</td> <td></td> </tr>
<tr class=”even> <td>row2</td> <td></td> </tr>
<tr class=”odd> <td>row3</td> <td></td> </tr>


Then in the CSS you have:

.odd {background-color:lightblue;}
.even {background-color:blue;}

This markup will style the table with the desired formatting, however, this solution breaks down if the table is dynamic or interactive such that rows can be added or removed. If you insert a row at the top of the table, you now have to use script to change the class name of every row in the table.

Using an nth-child selector, you don’t need any markup on the table rows themselves. Your style sheet simply contains:

tr:nth-child(odd) { background-color:lightblue;}
tr:nth-child(even) {background-color:blue;}

Now if you add or remove rows from the table, the styling remains correct without needing any script.

As you can see above, nth-child selectors accept the keywords ‘even’ and ‘odd’. These selectors also accept an argument of the formula an+b. The ‘a’ and ‘b’ values are constants and the ‘n’ value increments starting from 0 until there are no more elements possible to select.  For example, tr:nth-child(2n+1) would be evaluated as follows:

  • n=0, 2n+1 = 1, select the tr element which is a first child.

  • n=1, 2n+1 = 3, select the tr element which is a third child.

  • n=2, 2n+1 = 5, select the tr element which is the fifth child. 

As you follow the evaluation, you’ll notice that 2n+1 is equivalent to ‘odd’ and ‘2n’ is equivalent to even.  For simplicity, if ‘a’ is 1, you may omit ‘a’. ‘n+3’ selects every child starting from the 3rd child. If ‘a’ is 0, you may omit ‘an’.  ‘0n+6’ == ‘6’ which selects only the 6th child.  If ‘b’ is 0 you can omit ‘b’ from the formula. ‘3n’ selects every third child.

UI element state pseudo-classes

The UI element state pseudo-classes allow you to select UI elements based on their current state.You can select elements which are enabled or disabled, checked, or in an indeterminate state. This is useful, for example, if you want to remind your users to accept your EULA before downloading a trial. If the check box for your license agreement is unchecked you can add text to remind customers to check the box, and that text can be hidden when the box is already checked. It’s not that difficult to enable this scenario with script, but with UI element pseudo-classes you don’t need the complexity of script and your pages run faster.

Negation pseudo-class

The negation pseudo-class enables you to negate a simple selector. *:not(div) selects all elements except div elements, p:not(.explanation) selects all paragraphs not in the class ‘explanation’. The negation pseudo class can’t accept itself as an argument, so double negatives such as, :not(:not()), are not valid and pseudo elements are also not accepted as arguments to the ‘not’ selector.


The selection pseudo-element enables you to specify how you want content to look when users highlight text on your website. By default, when a user selects text in IE, the background color changes to blue and the text color changes to white:

a website with selected text, blue background, white text

Using the ::selection pseudo-element you can customize the selection text color and background color to fit the theme of your site. If you want to style selected text with an orange background and black text, as done at, you can apply the following selector:

::selection { 
a website with selected text, orange background, black text.

While the selection pseudo element is an interesting scenario, allowing arbitrary styling in this selector can cause some unintended side effects.  For example, if the selection pseudo element changes the font or the text size, that will change the size of text as the user selects it, creating a confusing experience. For this reason, IE only supports the color and background-color properties in the selection pseudo-element. This is equivalent to how other browsers support this selector.

In addition to limiting the properties which can be set through the ::selection pseudo class, IE9 defines a few default values for the case that a web developer only sets color or background-color but not both:

  • If only the color property is set then the ::selection background-color defaults to transparent

  • If only the background-color property is set then the color defaults to whatever color it was before it became part of the selection.(The color does not change)

  • If only non-supported CSS properties are set in the ::selection rule then the selection rule is ignored and the default IE selection styling is applied.

Observant readers may notice that the selector pseudo-element is not included in the most current version of the CSS3 Selectors draft. We implemented ::selection in support of our goal to allow developers to write same markup because we see it in use on the web and supported in other browsers.

CSS3 selectors add a lot of power to your style sheets. We’d love to hear about interesting ways you are using these selectors on your websites and certainly if you encounter any bugs with our implementation please let us know.

Sharon Newman
Program Manager

Edit 5/14: Updated ::selection to E::selection in the list of new supported selectors.

Comments (34)

  1. Anonymous says:

    @Rufus: why not disable CSS and images by default while we’re there? Oh, and HTML too, as it can be quite nasty.

    My experience is the opposite of yours: CSS has made things better. Back in the days, you had crappy HTML, frames, blinking text, and JS that blocked right clicks etc everywhere. Although some of this remains, such as floating Flash ads.

    Anyway, pages that have shitty design or usability will have fewer visitors, that’s all.

  2. Anonymous says:

    Thank you for sharing your article helped me a lot.

  3. Canvas says:

    Stop with the "same markup" lies until you have Canvas support.

  4. Anti-Troll says:

    canvas: is your theory that if you’re annoying, you’ll get your way? Most kids grow out of that before their tenth birthday. Have you hit that milestone yet?

    sharon: thank you!

  5. infinte says:

    <canvas> or <sence> or <stage> or direct manipulation of bitmap data of <img>

  6. karl says:

    infinite: What’s up with those mysterious elements html:sence and html:stage you are referring to?

    I can’t find them in any spec, nor searching the web.

    The only time i heard about them before was in the comments of another article of this blog. And i believe it was you who wrote that too, although if i am right you were a little bit less unfriendly then and perhaps a little more on topic, too.

  7. infinte says:


    The <sence> or <stage> are something that provides same function that <canvas> has but in the different interface.

  8. Gyrobo says:


    Could you provide a link to the spec that <sence> and <stage> are contained in? I’ve never heard of those either.

  9. Gyrobo says:

    @Sharon Newman

    The ::selection in your list at the very top is missing a preceding "E". Also, why no mention of the before, after, first-letter and first-line pseudo-elements? You might want to include a little note about the differences between pseudo-classes and pseudo-elements and why the notation was changed to two colons.

  10. hAl says:

    @ Gyrobo

    "Also, why no mention of the before, after, first-letter and first-line pseudo-elements?"

    Those are actually CSS2 elements and, as such, were supported in IE8 already as IE8 already  supports all elements in CSS 2.1 .

    They do contain some obscure bug though (even in IE9)–important-Rule-Ignore-Bug

  11. Johannes says:

    Since ::selection was removed from the W3C recommendation already, wouldn’t ::-ms-selection be to correct name for it? After all, it’s no longer a defined pseudo-element but rather a vendor-defined one.

    After all, you’ve done the same to various CSS properties in IE 8.

  12. beverloo says:

    How about the additional selectors associated with the Basic User Interface CSS 3 module? These are strongly connected with the Web Forms standard and adds extra selectors such as :invalid, :read-only, :out-of-range and :required. They can be found in the following (CR) spec:

    Furthermore I do agree with Gyrobo, some extra explanation about the double colons could make this article more understandable. It’s something new in CSS 3 and not a lot of people will have used it yet.

  13. Rufus says:

    Hopefully users will be able to disable/override at least the ::selection pseudo-element! I see a usability nightmare coming if web "designers" are able to override the color scheme of the text selection marker. Support for ::selection should be disabled by default.

    Web designers are overusing CSS these days to the extent that more and more web pages are becoming unusable – I have started to prefer mobile devices pages even on my desktop browser because of the simpler, cleaner and more usable design they offer.

    Users should be able to switch on the following elements: audio, video, canvas (these should be off by the default as well).

    audio, video, canvas should be integrated into InPrivate Browsing as well – or better yet: add a real junk filter (as blocker) into IE9 that is able to filter and block img, object, audio, video, canvas, …

    These days a browser needs native support for junk filtering, similar to email applications!

    Please, please, please, please!

  14. Daniel Glazman says:

    Superb. Mucho sincere congrats!

    If you have a few spare cycles, could you please submit an implementation report (à la [1]) to the CSS Working Group. I know the Selectors spec is already accepted as REC by the W3C Director but still, showing IE9 passes all tests here is a very good point since former versions of IE were failing so much at the Test Suite it was pointless to have them in the Implementation Report… Thanks.


    Daniel Glazman

    W3C CSS Working Group, Co-chairman

  15. IE9 Team, you just made my day.

    Thank you 🙂


  16. harold jr says:

    This is very exciting news!  Once IE9 ships I’m sure that developers everywhere will be excited to be able to finally use all these features seeing that IE has finally stepped up to the table with support.

    An interesting side-effect will take place however in that support and use of IE6 through IE8 will drop dramatically.

    I personally no longer support IE6 at all (not even a limited version… IE6 users are given an outdated browser warning with links to a randomized list of modern browser options (Firefox, Chrome, IE8, Safari, Opera).

    When IE9 ships, support for IE7 will also be dropped.  And users detected as running Vista or Win 7 will be prompted to upgrade to IE9 too.

    I’m so excited about all this.  Supporting the latest IE version will be sooooooooooo much more pleasant than any currently shipping IE version.

  17. This is very good. Could you please consider Canvas.

    Take a look at what this guy has been doing with HTML5 canvas


  18. Gary says:


    "Once IE9 ships I’m sure that developers everywhere will be excited to be able to finally use all these features seeing that IE has finally stepped up to the table with support.

    An interesting side-effect will take place however in that support and use of IE6 through IE8 will drop dramatically."

    That’s misguided at best. As much as we’d all love to be supporting just IE9, with it’s lack of support on XP and the slow take up by the masses, you’re still going to be supporting IE7 and IE8 for a while, if you don’t want to severely limit your / your clients target audience.

  19. Wurst says:

    So if I mix inverted (white-on-black) and normal text on my site then I have to care not to make selections hardly visible?

    IMHO, it would be better if the default foreground font colour of selected text depended on the selection colour, ie. if the background colour is dark then the text colour defaults to white, otherwise black. The same for the default background colour, so that when only the background colour xor the font colour is set for selected text, it always stays readable.

  20. Wurst says:

    @Björn Sveinbjörnsson:

    IMHO, this would have been a better use case for SVG (which would have made it also scalable).

  21. There is one area in CSS that is in particular troublesome, form elements. Would be very interesting to hear what MS’s thoughts on this is in relations to "same markup" and all these test cases submitted to make the W3C standard less ambiguous.

  22. Sharon [MSFT] says:

    @Gryobo – thanks I updated the item to E::selection in the list at the top.

    @Daniel Glazman – thanks.  I will work with Sylvain to get that done.

    @Wurst – thanks for the thoughts.  It’s an interesting idea.    

  23. Gyrobo says:


    "Those are actually CSS2 elements and, as such, were supported in IE8 already as IE8 already  supports all elements in CSS 2.1 ."

    True, but the double colon notation versions of those pseudo-elements is new. While I’m pretty sure it’s just a semantic change, I’d like to know if there are any function differences between single and double colon notation, which syntax is preferred for general use, whether they can be used interchangeably (the specificity of each).

  24. I see this as good news overall, but… Canvas support please?

  25. Edwin Martin says:

    For everybody asking for canvas support: the chance IE9 will support canvas is near 100%.

    "Why?", you’ll aks.


    1) Microsoft has drunk the html5 koolaid. It confirmed support for html5.

    2) Microsoft supports SVG, which is much harder to implement than canvas.

    3) The fear that Microsoft is protecting their own technologies (VML) does not apply: VML is much more like SVG than canvas. So, from this point of view, Microsoft would support canvas easier than SVG.

  26. Evan Byrne says:

    This is great news! As for the people complaining about ::selection, i really don’t see the issue. There are plenty of ways for you to screw up your website already, adding ::selection won’t cause your user’s social security numbers to get stolen.

  27. Badger says:

    @Evan Byrne  I completely agree.

  28. SS says:

    I would like to see canvas support please

  29. beverloo says:

    The problem with ::selection is that it got released as a Candidate Recommendation in November 2001, however, it got dropped again in March 2010 due a number of issues, mostly in relation to nesting the element and styling. Because of this UA’s currently implement the pseudo-selector in a different manner even though none (except for Firefox) require the vendor prefix. Whether they should is debatable  as the specification was published as a candidate recommendation and vendors shipped software with the feature before going back to a draft.

  30. Will Peavy says:

    Feature request- please make it easy for users to disable ::selection.

  31. Mustansir Doctor says:

    Scenario: I have 5 email accounts (gmail, hotmail, yahoo, etc). When I check email, I usually check them all. I also visit multiple news sites frequently (cnn, bbc,, Again, I usually open all of them at the same time.

    It would be great if I could fire up IE, open a few tabs, navigate to different sites in them, and then choose "Save Tabbed Session". I could then have multiple saved tab sessions (e.g., named "Email", "News", etc). The next time I start IE, I can then just choose "Load Tabbed Session", and choose one of my saved ones. Automatically, all necessary tabs would open up, with each navigating to one of the sites in the session.

    P.S. I couldn’t figure out how to give this suggestion via Connect. It seems Connect always assumes I am filing a bug agains the IE 9 Platform Preview.

  32. P says:

    I was wondering if IE9 supports returning computed values for CSS in JS.

  33. A Nonnymouse says:

    @Mustansir Doctor

    Doesn’t IE8 already do that?  

    Add Current Tabs to Favorites once the tabs you want are open.  Then click on the arrow next to the Favorites folder that was created to open all of them later.

    Or do you mean something else?

  34. Lars Gunther says:

    Mozilla have taken careful measures to stop queries into browser history based on the :visited selector. Will IE9 be equally safe in this regard?