Understanding nth-child(an + b): selector with formula in CSS3?

css, css-selectors

Solution

The `n` in `:nth-child()` actually starts counting from zero, rather than one. From the spec:

The value a can be negative, but only the positive values of `a``n`+`b`, for `n`≥0, may represent an element in the document tree.

Although it says that the index of the first child of 1, which indeed it is, what it's referring to is the result of the formula, not the value of `n`. In other words, the first child is represented by a function of `n` that evaluates to 1, not by a function of `n` where `n = 0` or `n = 1` (whichever it starts counting at).

So the formula `:nth-child(1n+1)` (or algebraically equivalent `:nth-child(n+1)`) evaluates for `n = 0` as:

  1n + 1
= 1(0) + 1
= 0 + 1
= 1

Which results in your first `div` being matched.

You need to start from 2 for the pseudo-class notation to work as expected:

.list-item > div:nth-child(1n+2) > i[class^="icon-"], 
.list-item > div:nth-child(1n+2) > i[class*=" icon-"]

Or to make things simpler, you can opt for the general sibling combinator `~` in conjunction with `:first-child` instead:

.list-item > div:first-child ~ div > i[class^="icon-"], 
.list-item > div:first-child ~ div > i[class*=" icon-"]

This has an added bonus of IE7/IE8 support, in case it matters.

Problem

The `<i>` used for icons and child of the first `<div>` should have a big icon. Any other `<i>` child of any `<div>` (but not the first) should have a medium size icon: ``` <div class="row list-item"> <div class="span1"> <i class="icon-user"></i> </div> <div class="span3"> <div> <a href="#">Main Link</a> <i class="icon-male"></i> </div> <i class="icon-mail"></i> <a href="#">Link 2</a> <i class="icon-mobile"></i> <a href="#">Link 3</a> </div> </div> ``` Relevant CSS: ``` .list-item > div:first-child { text-align: center; } .list-item i[class^="icon-"], .list-item[class*=" icon-"] { text-shadow: 3px 1px 2px rgba(0, 0, 0, 0.2); } /* Only i with icon-* class, where div is first child */ .list-item > div:first-child > i[class^="icon-"], .list-item > div:first-child > i[class*=" icon-"] { font-size: 60px; line-height: 80px; } /* Any i with icon-* class, where div is not first child */ .list-item > div:nth-child(1n+1) > i[class^="icon-"], .list-item > div:nth-child(1n+1) > i[class*=" icon-"] { vertical-align: middle; font-size: 24px; line-height: 24px; } ``` So i used offset in formula `nth-child(an + b)`, with `b = 1`. That is offset is 1 so first `<div>` should be skipped. But the first big icon is matched by the last rule. What i'm missing?

Original source