5

I have this code:

<html> 
    <head>
        <style type="text/css"> 
            * > ul li:nth-child(4n+3) { color: red; }
        </style> 
    </head>
    <body> 
        <ul>
            <li id="A" class="u">1</li> 
            <li>
                <ol> 
                    <li id="B" class="u">2.1</li>
                    <li id="C" class="g">2.2</li> 
                    <li id="D" class="u">2.3</li>
                    <li id="E" class="g">2.4</li> 
                </ol>
            </li> 
            <li id="F" class="u">3</li>
        </ul> 
    </body>
</html>

In this it selects 2.3 and 3 but I don't understand how this happens.

My thought is: It selects simultaneously two elements in odd position relative to the parent element. But is 2.3 really the 3rd position or 7? I am really stuck, please help.

JSFiddle Sample

Paul D. Waite
  • 96,640
  • 56
  • 199
  • 270
Raed K Hakim
  • 63
  • 1
  • 4
  • 1
    Ignoring the redundant `* >`, your selector means: "select every `li` that's the `4n+3`th child of its parent element, and is the descendant of a `ul` element". There's no such thing as "the" parent element with the nth-child selector. Each element on the page is checked to see if it's the nth-child relative to *its* parent element. – Paul D. Waite Jul 29 '13 at 12:01

3 Answers3

9
* > ul li:nth-child(4n+3)

Firstly, the * > at the start of this selector is entirely redundant (It tells the browser to look for a ul that is a child of something else; anything else. Which of course all ul elements are; if nothing else, they'll be inside the body tag).

So you can remove that. It'll make it simpler to work with and easier to explain.

Now we're left with this:

ul li:nth-child(4n+3)

The reason it's picking both 2.3 and 3 is because both your sets of li elements are descended from the single parent ul element. Using a space between selectors tells the browser to look for any descendants that match; it doesn't care about how far down the tree to look for matching li elements, so it finds both sets.

To answer your question about why 2.3 isn't seen as the seventh element in the set, the answer is that CSS sees each set of li elements as an entirely separate group; even if the selector happens to match two or more sets of elements as your original selector did, it will still run a separate counter for each, so 2.3 and 3 are both seen as the third element in their respective sets.

If you want to only select elements that are children of the ul (ie immediately below it in the heirarchy), you need to use the child selector (>) rather than just a space.

ul > li:nth-child(4n+3)

This will now only select the outer set of li elements, so only your 3 element will be picked up.

Hope that helps explain things.

By the way, on a more general note, you might find this useful: CSS '>' selector; what is it?

Community
  • 1
  • 1
Spudley
  • 166,037
  • 39
  • 233
  • 307
1

Item 2.3 is position 3 (n=0, 4n+3 = 3) in the innermost ol list. It's also selected because ul li part of the selectors means "all li elements inside any ul element, regardless of the nesting level". And the nth-child part adds one more condition: "those of them that are 3rd, 7th, 11th and so on child of their immediate parent".

Ilya Streltsyn
  • 13,076
  • 2
  • 37
  • 57
0

It's done relative to the parent:

#B = index 0

#C = index 1

#D = index 2

#E = index 3

-

4n means 4 multiplied by the item's index

+ 3 is, of course, plus 3 - meaning:

-

#B = index 0 = 4x0 = 0 + 3 = 3 (3rd element - index 2)

#C = index 1 = 4x1 = 4 + 3 = 7 (7th element - index 6)

#D = index 2 = 4x2 = 8 + 3 = 11 (11th element - index 10)

#E = index 3 = 4x3 = 12 + 3 = 15 (15th element - index 14)

MDEV
  • 10,730
  • 2
  • 33
  • 49