CSS предоставляет разработчикам гибкие инструменты для точечной стилизации веб-страниц. Среди них выделяются псевдоклассы :nth-child и :nth-of-type, которые помогают выбирать элементы по их позиции в структуре документа. На первый взгляд они кажутся похожими, но их поведение существенно отличается. В этой статье мы разберем их особенности, сравним их работу и покажем, как правильно применять каждый из них.

Псевдокласс :nth-child

Селектор :nth-child ориентируется на позицию элемента среди всех дочерних элементов родительского контейнера, не обращая внимания на их тип. Это значит, что он считает все теги подряд — будь то p, div или span.

Как это работает:

селектор:nth-child(порядковый_номер) {
  /* стили */
}

Параметр порядковый_номер может быть числом (например, 3), ключевым словом (odd для нечетных или even для четных) или выражением типа Xn + Y.

Как и ключевое слово, выражение Xn + Y используется для выбора сразу нескольких элементов, но по заданной закономерности, и расшифровывается следующим образом:

  • X - число, означающее порядковый интервал выбранных элементов
  • n - сохраняется в таком же виде, это множитель, который будет подставляться в формулу и увеличиваться на 1 начиная с 0
  • + или - - оператор, показывающий на то, нужно ли нам отклониться вперед или назад от каждого обозначенного порядковым интервалом селектора
  • Y - число, определяющее величину отклонения

Примеры использования числового порядкового номера в селекторе :nth-child

ul :nth-child(3)
Выберет каждый имеющийся третий элемент внутри ul

Причем работать такой селектор будет для элементов любого уровня вложенности.

 

ul li:nth-child(3)
Выберет каждый имеющийся третий элемент li внутри ul

При применении порядкового номера к конкретному селектору необходимо помнить о том, что данный селектор действительно должен быть под таким порядковым номером.

Для такой разметки:

<article>
  <p> ... какой-то текст ... </p>
  <p> ... какой-то текст ... </p>
  <span> ... какой-то текст ... </span>
  <p> ... какой-то текст ... </p>
</article>

селектор article p:nth-child(3) не отработает, т.к. 3й элемент - это span, а не p.

Примеры использования ключевого слова в селекторе :nth-child

ul li:nth-child(odd)
Выберет каждый имеющийся нечетный элемент li внутри ul

Обратите внимание, что для данной разметки селектор ul li:nth-child(even) не смотря на то, что выберет только все четные li внутри ul, закрасит красным абсолютно все элементы нумерованного списка.

Подумайте, почему? И ответ напишите в комментариях к статье )

Примеры использования выражения в селекторе :nth-child

p:nth-child(2n)
Выберет каждый второй элемент p

Поскольку множитель n начинает отсчет с 0, то селектор p:nth-child(2n) может быть эквивалентен следующему:

p:nth-child(0),
p:nth-child(2),
p:nth-child(4),
p:nth-child(6),
p:nth-child(8),
...  /* до бесконечности */

 

p:nth-child(2n+1)
Выберет все элементы p, индекс которых кратный двум со смещением +1.

Опять же, подставляя n можно представить, что это:

p:nth-child(1),
p:nth-child(3),
p:nth-child(5),
p:nth-child(7),
p:nth-child(9),
...  /* до бесконечности */

Смещение также может быть отрицательным - p:nth-child(3n-1), p:nth-child(2n-3).

В предыдущих примерах индексы выбираемых элементов возрастали, однако возможен и такой селектор - p:nth-child(-n+3), который будет эквивалентен:

p:nth-child(3),
p:nth-child(2),
p:nth-child(0),
p:nth-child(-1),  /* такой селектор просто будет игнорирован */
p:nth-child(-2),

Псевдокласс :nth-of-type

В отличие от :nth-child, селектор :nth-of-type фокусируется только на однотипных селекторах. Он делает выборки исключительно среди элементов указанного типа, игнорируя другие теги в родительском контейнере.

Синтаксис аналогичен :nth-child

селектор:nth-of-type(порядковый_номер) {
  /* стили */
}

В качестве порядкового номера может быть также число, ключевое слово или выражение.

Примеры использования селектора :nth-of-type

section p:nth-of-type(2)
Выберет второй p среди всех всех p, находящихся на одном уровне внутри элемента section

Обратите внимание на различие - элемент <div>Блок 1</div> является вторым среди всех элементов внутри seсtion, а элемент <p>Текст 2</p> является вторым среди всех p внутри section.

 

.title-2:nth-of-type(2)
Среди всех элементов с классом title-2 выберет тот (или те), который будет вторым среди своих типов

В данном примере классом title-2 помечены теги h2. Поскольку находящихся на одном уровне элементов h2.title-2 несколько, значит мы их можем пересчитать и присвоить стиль второму. Без привязки по типу этот же элемент внутри своего родителя будет 9-м.

Если вы обратили внимание, в описании селектора выше был текст "выберет тот (или те)". Такое может случиться, если один и тот же класс будет у разного типа элементов.

В данной разметке у нас класс title-2 есть у h2, h4 и p. Проходясь по каждому .title-2 браузер проверяет - является ли этот элемент вторым среди своих типов и если да - стилит его.

Как выбрать правильный селектор?

  • Используйте :nth-child, если вам нужно стилизовать элемент по его позиции в общем списке дочерних элементов, например, для раскраски строк таблицы или элементов в меню.
  • Применяйте :nth-of-type, если задача — стилизовать элементы одного типа, например, только определенные параграфы или заголовки, независимо от других тегов

Селекторы :nth-child и :nth-of-type — это мощные инструменты для точной стилизации в CSS. Понимание их различий поможет вам создавать более гибкие и предсказуемые стили. Экспериментируйте с этими псевдоклассами в своих проектах, чтобы лучше понять их возможности и сделать ваш код чище и эффективнее.