Как правило, в верстке современных макетов есть какое-то количество повторяющихся элементов, которые нужно отформатировать по-разному. Например, добавить разные изображения или цвет фона / текста / рамки. Для этого мы можем использовать селекторы :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.
