CSS :first-child, :nth-child, and :last-child are not like :eq

August 26, 2012 Mark Rushakoff

One mistake I’ve seen made a few times is the notion that CSS’s nth-child pseudoselector acts like jQuery’s :eq pseudoselector.

jQuery’s :eq(n) pseudoselector gives you a single element that is at index n out of all matched elements. While this is certainly a useful selector to have, it’s unfortunately not supported in standard CSS. If you find yourself repeatedly using :eq in your jQuery code, be careful that you are not relying too heavily on :eq to the point where your styles are difficult to match in “pure” CSS.

If we were to express :nth-child in terms of the :eq selector, it would be like using :eqscoped to all of the immediate descendant contents of a single element. Or in my own words, :nth-child adds a constraint to the selector that the matched element must be the nth element in its parent container.

So if we had a snippet of HTML like

<div>
    <div id="bar1" class="foo"></div>
    <div id="bar2" class="foo"></div>
    <div id="bar3" class="foo"></div>
</div>

Then the selector .foo:nth-child(2)will match the div #bar2. If we insert another element at the front of the container:

<div>
    <p>Shift!</p>
    <div id="bar1" class="foo"></div>
    <div id="bar2" class="foo"></div>
    <div id="bar3" class="foo"></div>
</div>

And again we select .foo:nth-child(2), we match the div #bar1 because the 2nd child of the container also matches .foo.

Thus, in this second example, if we try .foo:nth-child(1) or the equivalent .foo:first-child, we will not match any elements because the first child element in that container — the p tag — does not match .foo.

Likewise, :nth-child can match children in multiple containers. In the HTML snippet:

<div>
    <p>Shift!</p>
    <div id="bar1" class="foo"></div>
    <div id="bar2" class="foo"></div>
    <div id="bar3" class="foo"></div>
</div>

<div>
     <div id="quux" class="foo"></div>
</div>

the selector .foo:last-child will match the divs #bar3 and #quux; but .foo:first-child or .foo:nth-child(1) will only match #quux because the first child of the first container is, again, not a .foo.

 

About the Author

Biography

More Content by Mark Rushakoff
Previous
In the beginning there was; The Sample Project
In the beginning there was; The Sample Project

It can be stifling to jump into a big project as a new user or team member, you don't want to accidentally...

Next
Facebook's Data Team Challenges Fears of an Online Echo Chamber
Facebook's Data Team Challenges Fears of an Online Echo Chamber

Online pundits and media critics warn that as social media increasingly becomes a dominant source of news, ...