Как правило, в верстке современных макетов есть какое-то количество повторяющихся элементов, которые нужно отформатировать по-разному. Например, добавить разные изображения или цвет фона / текста / рамки. Для этого мы можем использовать селекторы :nth-child(n)
или :nth-of-type(n)
. В чем же между ними разница?
Однако, сначала давайте разберемся с тем, как мы можем записывать эти селекторы.
Селекторы псевдоклассов :nth-child
Эти селекторы работают с деревом документа, которое подразумевает, что внутри одного элемента может располагаться несколько дочерних элементов. Именно для них и стоит использовать нужные селекторы типа :nth-child
.
Варианты выбора на примере :nth-child
:first-child
- выбирает первый элемент у своего родителя:last-child
- выбирает последний элемент у своего родителя:nth-child(3)
- выберет 3-й элемент у своего родителя:nth-child(3n)
- выбирает каждый 3-й элемент у своего родителя:nth-child(3n+1)
- выбирает каждый 3-й элемент у своего родителя и сдвигает этот выбор на один элемент ниже. То есть 4-ый, 7-ой, 10-й и т.п. элемент.:nth-child(3n-1)
- выбирает каждый 3-й элемент у своего родителя и сдвигает этот выбор на один элемент выше. То есть 2-ый, 5-ый, 8-й и т.п. элемент. Аналогом является:nth-child(3n+2)
:nth-child(n+5)
- выберет все элементы начиная с 5-го.:nth-child(-n+5)
- выберет 5 элементов с начала своего родителя.
Примечание: несмотря на то, что селектор :nth-child()
или :first-child
выберет первый элемент, когда вы указываете множитель, например, :nth-child(3n+1)
, в множитель будет вначале подставлено число 0.
Ключевые слова: even (четные элементы) и odd (нечетные)
:nth-child(even)
=:nth-child(2n)
— выбирает четные элементы у своего родителя, как если бы мы задали (2n).:nth-child(odd)
=:nth-child(2n+1)
— выбирает нечетные элементы, как если бы мы задали (2n+1).
Вы можете проверить сами, как работает этот селектор, вставляя в поле любые комбинации в виде 4n+1
или ключевые слова even
и odd
. Не будет работать пример для :first-child
и :last-child
.
See the Pen Choosing :nth-child by Elen (@ambassador) on CodePen.
Селекторы псевдоклассов :nth-of-type
Вы далеко не всегда будете иметь разметку, в которой внутри родительского элемента будут находится однотипные дочерние элементы. В том случае, если такие элементы разного типа, например, заголовок и несколько колонок, селекторы :nth-child
будут работать для них всех, вне зависимости от типа элемента. Далеко не всегда это бывает удобным.
В примере ниже вы видите 3 блочных элемента, для которых заданы разные цвета верхней рамки, иконки и заголовка. Все это отлично работает, когда эти блоки находятся в разметке родительского div
с классом container
. Однако, при нажатии на кнопку "Добавить заголовок" внизу ситуация с распределением цветов меняется.
See the Pen nth-child Problem by Elen (@ambassador) on CodePen.
Если вы уже нажали кнопку, то, возможно, задались вопросом - почему же так происходит? С чего бы это вдруг появление еще одного элемента БЕЗ класса .box
меняло внешний вид других элементов, у которых этот класс есть?
Так что же происходит при добавлении заголовка в html-документе? Меняется DOM-структура документа и, в частности, элемента div.container
. Первым элементом ДО появления заголовка был левый div.box
, вторым - средний div.box
, а последним - правый div.box
. Поэтому все стили работали корректно. При появлении заголовка ПЕРВЫМ элементом становится заголовок, но для него нет стилей, связанных с синим цветом текста, поэтому он никак не меняется. Вторым становится левый div.box
- и он меняет синие оттенки на зеленые, средний элемент становится 3-м по счету, но для него стилей нет. Ну, а последний элемент остается последним и ДО, и ПОСЛЕ добавления заголовка, поэтому для него ничего не меняется. На рисунке выше все изменения показаны стрелками.
Вот тут мы и подходим к необходимости использовать псевдоклассы :nth-of-type
, потому что все их отличие от :nth-child
заключается в том, что все те же правила форматирования, что были выше, работают для типа элемента или, точнее, для типа селектора. То есть для абзацев или для элементов с определенным классом и т.п.
Тот же пример, что был у нас выше, перепишем с использованием стиле для .box:nth-of-type
.
See the Pen nth-child Problem by Elen (@ambassador) on CodePen.
В примере ниже вы можете попробовать разные варианты селекторов + псевдоклассов :nth-of-type
.
See the Pen Choosing :nth-of-type by Elen (@ambassador) on CodePen.
В футере представленного ниже примера мы выбираем каждый второй элемент внутри div.container
с помощью селектора footer .container > :nth-of-type(2n)
.
See the Pen nth-of-type by Elen (@ambassador)on CodePen.
Тест по селекторам
Проверьте себя, пройдя тест от Paulina Hetman. Он посвящен не только псевдоклассам, но в нем вы встретите и :nth-chiled
, и :first-of-type
.
See the Pen QUIZ: Well aimed? How well do you know CSS selectors? by Elen (@ambassador) on CodePen.