Понимание nth-child (a + b): селектор с формулой в CSS3?

<i>, используемый для значков и дочернего элемента первого <div>, должен иметь большой значок. Любой другой <i> ребенок любого <div> (но не первого) должен иметь значок среднего размера:

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

Соответствующий 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;
}

Итак, я использовал смещение в формуле nth-child(an + b), с b = 1. Это смещение равно 1, поэтому сначала <div> следует пропустить. Но первый большой значок соответствует последнему правилу. Что мне не хватает?

Ответ 1

n в :nth-child() фактически начинает отсчет с нуля, а не на один. Из spec:

Значение a может быть отрицательным, но только положительные значения an + b, для n ≥0, могут представлять собой элемент в дереве документов.

Хотя он говорит, что индекс первого дочернего элемента из 1, который действительно является тем, на что он ссылается, является результатом формулы, а не значением n. Другими словами, первый дочерний элемент представлен функцией n, которая оценивается как 1, а не функцией n, где n = 0 или n = 1 (в зависимости от того, что она начинает отсчитывать).

Итак, формула :nth-child(1n+1) (или алгебраически эквивалентная :nth-child(n+1)) оценивает для n = 0 как:

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

В результате получается ваш первый div.

Вам нужно начать с 2, чтобы обозначение псевдокласса работало, как ожидалось:

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

Или, чтобы упростить задачу, вы можете выбрать общий комбинированный комбинатор ~ в сочетании с :first-child вместо:

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

У этого есть дополнительный бонус поддержки IE7/IE8, если это имеет значение.