meyerweb.com

Skip to: site navigation/presentation
Skip to: Thoughts From Eric

Combining ‘nth-of-type()’ With Negation

I just recently came across one of those things that’s really obvious once you stop to think about it, and might be really obvious if you think about it from the right angle, but can trip you up if you come at it from a slightly different direction.

Consider the following two rules, which are equivalent:

li:not(.skip):nth-of-type(odd);
li:nth-of-type(odd):not(.skip);

First off, the order doesn’t matter.  The result is exactly the same no matter which way you write it, which is why I wrote the same thing twice.

Either way, the selector will select the odd-numbered li elements that share a common parent, but not those which have a class of skip.  What it does not do is select the odd-numbered li elements without a class of skip that share a common parent.

Did you catch the distinction?  Natural-language ambiguity (languaguity?) may obscure the precise meaning.  Here’s some example markup (adapted from a test file I set up):

<ul>
   <li>Item 1</li>
   <li>Item 2</li>
   <li class="skip">Item 3</li>
   <li>Item 4</li>
   <li>Item 5</li>
   <li>Item 6</li>
</ul>

The list items selected by either of the previous selectors will be numbers 1 and 5.  Numbers 4 and 6 will never be selected, because they are not odd-numbered members of this set of li elements.  Remember, nth-of-type() refers to element types, as in li or p or h4.  It doesn’t refer to “this type of thing that I am trying to describe here in this whole selector”.

Another way of stating this is that the negation pseudo-class does not act as a filter for the :nth-of-type() portion of the selector.  There is no “do this, then that” ordering of pseudo-classes.  They must both apply, considered independently of each other, for an element to be matched.  (This may remind you of the effects caused by the lack of element proximity, though the root causes are rather different.)

There is a (fairly solid-looking) proposal in CSS4 Selectors called :nth-match() that should allow authors to set up a condition where list items 4 and 6 get selected—for example, :nth-match(odd of li:not(.skip)), unless of course the syntax gets changed—but that’s for the future.  For now, if you need to select every other element of a matched set, you’ll need some scripting to help you out.

Five Responses»

    • #1
    • Comment
    • Tue 12 Jun 2012
    • 1717
    Brendan wrote in to say...

    Super interesting. I’m assuming you meant the opening and closing tags of the list itself to match though?

    • #2
    • Comment
    • Tue 12 Jun 2012
    • 1759
    iDGS wrote in to say...

    Very nice. The idea that the selector, albeit “complicated-looking” is *not* a “program” that runs in sequence is a genuinely helpful clarification! FWIW, I now appreciate it as being more like a pair of overlaid filters, which, when combined, only select those items where each filter has a “hole” that lines up with a hole in the other, allowing the underlying item to be seen. (One of those things where a simple diagram might also help.) Or, in other words, the components of the selector are joined by an implicit logical AND. As in, both (phrase A) AND (phrase B) must be true in order for the element to be selected. I’m surely botching the point–you can do better–but to anyone with a smidgeon of boolean algebra in their background, like old programmers who’ve taken a shine to web design (*cough, cough*), that might likewise help increase the overall level of illumination. Or\\And not. ;-)

    • #3
    • Comment
    • Tue 12 Jun 2012
    • 2303
    Eric Meyer wrote in to say...

    Er, um, yes, Brendan. Fixed. Thanks!

    Glad to be of assistance, iDGS!

    • #4
    • Pingback
    • Tue 19 Jun 2012
    • 0404
    Received from Some links for light reading (19/6/12) | Max Design

    [...] Combining ‘nth-of-type()’ With Negation [...]

    • #5
    • Pingback
    • Mon 9 Jul 2012
    • 1839
    Received from Quality Linkery: Week Three | shawnhayden.com

    [...] Combining ‘nth-of-type()’ With Negation [...]

Leave a Comment

Line and paragraph breaks automatic, e-mail address required but never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>



Remember to encode character entities if you're posting markup examples! Management reserves the right to edit or remove any comment—especially those that are abusive, irrelevant to the topic at hand, or made by anonymous posters—although honestly, most edits are a matter of fixing mangled markup. Thus the note about encoding your entities. If you're satisfied with what you've written, then go ahead...


June 2012
SMTWTFS
May September
 12
3456789
10111213141516
17181920212223
24252627282930

Sidestep

Feeds

Extras