Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the nth-child selector select these elements?

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

like image 998
Raed K Hakim Avatar asked Jul 29 '13 11:07

Raed K Hakim


2 Answers

* > 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?

like image 104
Spudley Avatar answered Oct 13 '22 12:10

Spudley


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".

like image 45
Ilya Streltsyn Avatar answered Oct 13 '22 12:10

Ilya Streltsyn