Псевдоклассы CSS: nth-child и nth-of-type. Количественные CSS селекторы
Псевдокласс :nth-last-child используется для добавления стиля к элементам на основе нумерации в дереве элементов. В отличие от псевдокласса :nth-child отсчёт ведётся не от первого элемента, а от последнего.
Обозначения
Описание | Пример | |
---|---|---|
<тип> | Указывает тип значения. | <размер> |
A && B | Значения должны выводиться в указанном порядке. | <размер> && <цвет> |
A | B | Указывает, что надо выбрать только одно значение из предложенных (A или B). | normal | small-caps |
A || B | Каждое значение может использоваться самостоятельно или совместно с другими в произвольном порядке. | width || count |
Группирует значения. | [ crop || cross ] | |
* | Повторять ноль или больше раз. | [,<время>]* |
+ | Повторять один или больше раз. | <число>+ |
? | Указанный тип, слово или группа не является обязательным. | inset? |
{A, B} | Повторять не менее A, но не более B раз. | <радиус>{1,4} |
# | Повторять один или больше раз через запятую. | <время># |
Значения
odd Все нечётные номера элементов, начиная с конца. even Все чётные номера элементов, начиная с конца. <число> Порядковый номер дочернего элемента относительно своего родителя. Нумерация начинается с 1, это соответствует последнему элементу в списке. <выражение> Задаётся в виде an±b , где a и b целые числа, а n - счётчик, который автоматически принимает значение 0, 1, 2...
Если a равно нулю, то оно не пишется и запись сокращается до b . Если b равно нулю, то оно также не указывается и выражение записывается в форме an . a и b могут быть отрицательными числами, в этом случае знак плюс меняется на минус, например: 5n-1.
За счёт использования отрицательных значений a и b некоторые результаты могут также получиться отрицательными или равными нулю. Однако на элементы оказывают влияние только положительные значения из-за того, что нумерация элементов начинается с 1.
В табл. 1 приведены некоторые возможные выражения и ключевые слова, а также указано, какие номера элементов будут задействованы. Отсчёт ведётся от последнего элемента.
Значение | Номера элементов | Описание |
---|---|---|
1 | 1 | Последний элемент, является синонимом псевдокласса :last-child . |
5 | 5 | Пятый элемент с конца. |
2n | 2, 4, 6, 8, 10,… | Все чётные элементы, начиная с конца; аналог значения even . |
2n+1 | 1, 3, 5, 7, 9,… | Все нечётные элементы, начиная с конца; аналог значения odd . |
3n | 3, 6, 9, 12,… | Каждый третий элемент, начиная с конца. |
3n+2 | 2, 5, 8, 11, 14,… | Каждый третий элемент, начиная с предпоследнего. |
n+4 | 4, 5, 6, 7, 8,… | Все элементы, кроме последних трёх. |
-n+3 | 3, 2, 1 | Последние три элемента. |
5n-2 | 3, 8, 13, 18, 23,… | — |
even | 2, 4, 6, 8, 10,… | Все чётные элементы, начиная с конца. |
odd | 1, 3, 5, 7, 9,… | Все нечётные элементы, начиная с конца. |
Пример
2134 | 2135 | 2136 | 2137 | 2138 | |
Нефть | 16 | 34 | 62 | 74 | 57 |
Золото | 4 | 69 | 72 | 56 | 47 |
Дерево | 7 | 73 | 79 | 34 | 86 |
Камни | 23 | 34 | 88 | 53 | 103 |
В данном примере псевдокласс :nth-last-child используется для выделения цветом всех нечётных колонок, начиная с последней (рис. 1).
Рис. 1. Применение псевдокласса:nth-last-child к колонкам таблицы
Спецификация
Каждая спецификация проходит несколько стадий одобрения.
- Recommendation (Рекомендация ) - спецификация одобрена W3C и рекомендована как стандарт.
- Candidate Recommendation (Возможная рекомендация ) - группа, отвечающая за стандарт, удовлетворена, как он соответствует своим целям, но требуется помощь сообщества разработчиков по реализации стандарта.
- Proposed Recommendation (Предлагаемая рекомендация ) - на этом этапе документ представлен на рассмотрение Консультативного совета W3C для окончательного утверждения.
- Working Draft (Рабочий проект ) - более зрелая версия черновика после обсуждения и внесения поправок для рассмотрения сообществом.
- Editor"s draft (Редакторский черновик ) - черновая версия стандарта после внесения правок редакторами проекта.
- Draft (Черновик спецификации ) - первая черновая версия стандарта.
CSS nth-child — это псевдокласс, используемый для выбора элементов с помощью числового выражения. Его синтаксис на первый взгляд может показаться немного запутанным.
В этой статье мы рассмотрим:
- различные способы использования :nth-child ;
- более гибкий селектор :nth-of-type ;
- и связанные с ними селекторы :nth-last-child и :nth-last-of-type .
:nth-last-of-type
:nth-last-of-type выбирает дочерние элементы, если их позиция в документе совпадает с шаблоном, описываемым алгебраическим выражением.
Селектор :nth-last-of-type выглядит примерно так:
li:nth-child(выражение); {}
«Выражение » может быть представлено ключевыми словами even или odd , целым числом или формулой по типу an+b , где a и b — целые числа, положительные или отрицательные.
Поскольку псевдокласс CSS nth child может использоваться для выбора диапазона различных элементов. Давайте рассмотрим несколько примеров, чтобы стало понятнее.
У меня есть маркированный список из 12 элементов. Посмотрим, как можно использовать :nth-child для выбора определенного элемента или набора элементов по шаблону:
- lorem ipsum
- lorem ipsum
- lorem ipsum
- lorem ipsum
- lorem ipsum
- lorem ipsum
- lorem ipsum
- lorem ipsum
- lorem ipsum
- lorem ipsum
- lorem ipsum
- lorem ipsum
Чтобы выбрать третий элемент списка, нужно указать li:nth-child(3) . Чтобы выбрать все четные элементы, можно использовать ключевое слово even. И наоборот, можно использовать :nth-child(odd) , чтобы выбрать все элементы с нечетным номером.
CSS nth child каждый 3 й — указываем li:nth-child(3n) . Чтобы выбрать первые четыре элемента, используем li:nth-child(-n+4) . Чтобы выбрать все, кроме первых четырех элементов, можно использовать li:nth-child(n+5) .
Выражение an + b
Альтернативой использованию ключевого слова odd является использование выражения 2n+1 . Но как это работает?
Когда выражение в формате an+b содержит отличные от ноля значения a и b , дочерние элементы разбиваются на группы. Если это выражение 2n+1 , дочерние элементы разбиваются на группы по два. Каждому элементу в группе присваивается индекс, начиная с 1 . Соответствующий элемент в каждой группе — это индекс номер b . В нашем примере это будет первый элемент.
Если выражение 3n+2 , элементы группируются по три элемента, и второй элемент в каждой группе соответствует выражению.
Если значение b является отрицательным, соответствующим в группе является элемент с индексом b . Но отсчитывается он в обратном направлении от индекса 1 . В этом случае соответствующий элемент будет принадлежать не данной, а предшествующей группе.
Ключевое слово even в CSS nth child может быть выражено как 2n . В этом случае у нас нет значения b , поэтому выбирается каждый элемент группы с индексом a ; 2n выбирает каждый второй элемент, 3n — каждый третий, 4n — каждый четвертый и так далее.
Лично я считаю, что концепция разбивки дочерних элементов на группы и поиска индекса соответствия для каждой группы очень запутана. Хотя именно так их описывает спецификация CSS-селекторов .
Мне больше нравится концепция поиска каждого n-ного элемента — каждого 2-го, 3-го или 4-го и т.д. А потом мне проще представить, что вторая часть выражения — это смещение.
В случае 2n+1 я читаю это выражение следующим образом: «Найти каждый второй элемент и переместить выделение вниз на 1 ».
Если выражение 3n-5 , оно будет читаться так: «Найти каждый третий элемент и переместить выделение вверх на 5 ».
Другие селекторы:nth-child
:nth-child имеет соответствующий ему псевдокласс :nth-last-child , который работает наоборот.
li:nth-last-child(3n) начинает с последнего дочернего элемента и обрабатывает их в обратном направлении, сопоставляя каждый третий элемент с конца списка.
Этот псевдокласс менее распространен. Тем не менее, часто необходимо выбрать первый или последний дочерний элемент. Это можно сделать с помощью :nth-child(1) или :nth-last-child(1) , но этот метод встречается не так часто, как псевдоклассы :first-child и :last-child . При этом только :first-child работает в IE8 , а :last-child и :nth-селекторы — нет.
:nth-of-type
Что меня часто не удовлетворяет, так это то, что псевдокласс CSS nth child отбирает дочерние элементы по индексу и не учитывает тип элемента.
Рассмотрим следующий пример.
Aenean commodo ligula eget dolor. Vestibulum dapibus nunc ac augue; Nunc sed turpis. Donec posuere vulputate arcu;lorem ipsum;
Есть раздел с заголовком, подзаголовком и несколькими абзацами. Я хочу, чтобы первый абзац немного выделялся с помощью увеличенного размера шрифта 1.5em .
Можно попробовать применить код section p:first-child , так как нужно задать дополнительный стиль для первого абзаца в этом разделе. Но это не сработает, поскольку первый дочерний элемент раздела — h1 . В этом случае необходимо использовать селектор :first-of-type .
Существует целый ряд селекторов этого типа — :first-of-type , :last-of-type , :nth-of-type и :nth-last-of-type . Они ведут себя так же, как :nth-child , но отбирают n-ые экземпляры элементов определенного типа.
Эти селекторы довольно сложны, но они предоставляют большие возможности. Они поддерживаются всеми браузерами, начиная с IE9 , в IE8 поддерживается только :first-child . В прошлом они не раз помогли мне решить несколько сложных задач.
Перевод статьи «AtoZ CSS Screencast: nth-child and nth-of-type » дружной командой проекта
Как задать стили отдельному объекту веб-страницы? Общепринятый способ — назначить класс, идентификатор, или обратиться по тегу. Но такая верстка не всегда работает. Особенно когда дело касается вложенных меню, последних элементов списка, CSS-стилей активных или посещенных ссылок. Именно для таких случаев были созданы псевдоклассы. Это особый вид селекторов, которые берегут нервную систему разработчика и существенно упрощают верстку.
Синтаксис и правила использования псевдоклассов
Отличительной чертой псевдоклассов является двоеточие. Именно этот знак отличает их от обычных селекторов. После двоеточия обязательно без пробела идет имя псевдокласса. В конце, если есть необходимость, в скобках указывается значение в виде целого числа, формулы или ключевого слова.
Li:last-child{ padding-bottom: 0; }
Иногда можно встретить двойное написание (::). Эта спецификация была добавлена в CSS3 для обращения к псевдоэлементам::backdrop, ::before, ::after. Они отличаются тем, что добавляют стили объектам, которых нет в дереве DOM. Например, заглавная буква или первая строка.
P::before{ content: ""; display: block; width: 100%; color: #222; }
Все тридцать селекторов мы разбирать не будем, возьмем только те, что означают в CSS последний элемент (:last-child), первый (:first-child). А также рассмотрим специальный псевдокласс (:nth-child), который позволяет обращаться к дочерним элементам по порядковому номеру. Учиться будем на примере создания панели навигации по сайту:
Получилось простое меню с четырьмя ссылками белого цвета. С помощью псевдоклассов мы можем выборочно настраивать каждый пункт навигации, менять размер, или сделать их разноцветными. Например, чтобы указать в CSS последний элемент красного цвета, а первый зеленого, нужен следующий код:
Nav a:first-child{ color: green; } nav a:last-child{ color: red; }
Универсальный селектор:nth-child
Этот селектор относится к числу структурных псевдоклассов. С его помощью можно управлять объектами по их нумерации. Порядковое число указывается в скобках и начинается с единицы. Если нужен последний элемент в CSS, для этого используется запись:
/*добавит последнему элементу справа границу красного цвета*/ nav a:nth-child(-1){ border-right: 1px solid red; }
Помимо целочисельных значений:nth-child принимает в качестве значений ключевые слова:
- odd - нечетные элементы;
- even - четные.
Теперь чтобы добавить границу желтого цвета каждой второй ссылке в панели навигации, достаточно прописать:
Nav a:nth-child(even){ border-bottom: 1px solid yellow; }
Комбинированное использование псевдоклассов
Каскадные таблицы стилей позволяют комбинировать в одном селекторе сразу несколько псевдоклассов. Такой подход может пригодиться, когда необходимо назначить определенные стили всем CSS элементам, кроме последнего.
Nav a:not(:last-child){ padding-right: 10px; }
Дословно запись выше указывает браузеру добавить ко всем ссылкам внутри навигации
Теперь, зная о возможности комбинирования селекторов, добавим нашей панели навигации интерактивности. Для этого будем использовать псевдокласс состояния:hover, который добавляет нужные стили при наведении курсора мышки на объект.
С помощью селектора nav a:hover, мы сделали так, чтобы внешний вид ссылок каждый раз менялся при наведении курсора. Так пользователю будет намного проще и интересней взаимодействовать с сайтом. Обратите внимание на запись nav a:nth-child(n). Благодаря ей у каждого пункта меню свой цвет подчеркивания в состоянии:hover.
Можно пойти дальше и добавить:focus и:active для элементов , которые будут менять поведение ссылок во время нажатия. Или окрасить их в другой цвет и увеличить размер шрифта в активном состоянии. С помощью CSS-селекторов оживают даже статичные HTML-страницы и без намека на JavaScript.
Новые псевдоклассы
Псевдоклассы CSS предназначены для выбора элементов на основании информации, не входящей в документ, или информации, которая не может быть выражена обычными селекторами. Вероятно, вы уже использовали псевдоклассы ранее - например, :hover для изменения цвета ссылки, когда пользователь наводит на нее указатель мыши. В CSS3 появилось несколько новых псевдоклассов, заметно упрощающих поиск элементов.
Для начала рассмотрим простой пример таблицы, на которой и будем испытывать новые псевдоклассы:
Перед вами довольно стандартный счет с ценами, количеством единиц товара, суммами строк, промежуточной суммой и общей суммой заказа. Счет было бы удобнее просматривать, если бы строки были окрашены в разные цвета. Также будет полезно изменить цвет итоговой суммы, чтобы она лучше выделялась на общем фоне.
Ниже приведен код таблицы и ее базовое стилевое оформление:
Продукт | Цена | Количество | Общая стоимость |
---|---|---|---|
Кофе | 30 | 5 | 150 |
Рубашка | 400 | 2 | 800 |
Красный степлер | 50 | 4 | 200 |
Общая стоимость | 1150 | ||
Доставка | 120 | ||
Итого | 1270 |
Table { width: 600px; border-collapse: collapse; } th, td { border: none; } th { background-color: #000; color: #fff; }
Чередование цвета строк (:nth-of-type)
Каждый из нас неоднократно видел таблицы с чередованием цвета строк (эффект зебры): этот эффект полезен тем, что упрощает просмотр данных по строкам. Стилевое оформление такого рода лучше всего выполняется средствами уровня представления, то есть CSS. Традиционно задача решалась включением в строки таблицы дополнительных имен классов (например, odd и even для нечетных и четных строк соответственно).
Однако подобное загрязнение разметки таблицы нежелательно, поскольку спецификация HTML5 рекомендует избегать использования имен классов для определения представления. При помощи новых селекторов мы сможем добиться желаемого эффекта без изменения разметки - таким образом, представление будет отделено от контента.
Селектор nth-of-type находит каждый n-й элемент конкретного типа, определяемый формулой или ключевыми словами. Формулы будут более подробно рассмотрены позднее, а пока разберемся с ключевыми словами, потому что их проще понять.
Чтобы каждая вторая строка таблицы была окрашена в другой цвет, проще всего найти все четные строки таблицы и назначить им другой цвет фона. То же самое делается с нечетными строками. В CSS3 имеются ключевые слова even и odd , предназначенные именно для таких ситуаций:
Tr:nth-of-type(even) { background-color: #DCC; } tr:nth-of-type(odd) { background-color: #F3F3F3; }
Фактически этот селектор означает: "Найти каждую четную строку таблицы и задать ее цвет. Затем найти каждую нечетную строку таблицы и задать ее цвет. Так "зебровая" окраска таблицы реализуется без использования сценарного кода или дополнительных имен классов в строках.
Очередная версия стилевого оформления таблицы выглядит так:
Выравнивание текста столбцов (:nth-child)
По умолчанию текст во всех столбцах таблицы выравнивается по левому краю. Мы выровняем по правому краю все столбцы, кроме первого - чтобы цена и количество единиц товара лучше читались. Для этого мы воспользуемся селектором nth-child , но сначала необходимо узнать, как он работает.
Селектор nth-child ищет дочерние элементы заданного элемента; по аналогии с nth-of-type, он может использовать ключевые слова или формулу. Формула определяется в виде an+b, где а - множитель, a b - смещение. Принцип использования формул проще понять на примере. Давайте применим его к контексту таблицы. Для выбора всех строк таблицы можно воспользоваться селектором вида:
Tr:nth-child(n)
В этом примере не указан ни множитель, ни смещение. Все строки таблицы, кроме первой (строка с заголовками столбцов), выбираются при помощи селектора со смещением:
Tr:nth-child(n+2)
А для выбора каждой второй строки таблицы используется множитель 2n:
Tr:nth-child(2n)
Каждая третья строка выбирается при помощи множителя 3n. Если прибавить к множителю смещение, то поиск будет начинаться не от начала таблицы, а с одной из следующих строк. Следующий селектор находит каждую вторую строку, начиная с четвертой:
Tr:nth-child(2n + 4)
Итак, для выравнивания всех столбцов, кроме первого, используется следующая запись:
Td:nth-child(n+2) { text-align: right; }
Выделение последней строки (:last-child)
Таблица уже сейчас смотрится вполне прилично, но начальство требует, чтобы нижняя строка выделялась жирным шрифтом. Для этого мы воспользуемся селектором last-child , который находит последний дочерний элемент группы:
Tr:last-child { font-weight:bold; }
Поиск в обратном направлении (:nth-last-child)
Если стоимость доставки снижена под действием скидки, то соответствующая строка таблицы должна выделяться цветом. Для быстрого поиска этой строки удобно использовать селектор nth-last-child . Вы уже видели, как селектор nth-child и формула an+b используются для выбора конкретных дочерних элементов. Селектор nth-last-child работает практически так же, если не считать того, что он перебирает дочерние элементы в обратном порядке, начиная с последнего. Это позволяет легко найти предпоследний элемент группы, что, собственно, и нужно сделать в нашем примере.
Итак, оформление строки со стоимостью доставки может быть изменено следующим кодом:
Tr:nth-last-child(2) { color: green; }
Селектор определяет конкретный дочерний элемент - второй с конца.
От автора: в CSS есть селекторы для поиска элементов на основе их положения в дереве документа. Их называют индексными псевдоклассами, потому что они смотрят на положение элемента, а не на его тип, атрибуты или ID. Всего их пять.
:first-child и:last-child
По названию вы могли догадаться, что псевдоклассы:first-child и:last-child выбирают первый и последний дочерний элемент в узле (элементе). Как и с другими псевдоклассами, :first-child и:last-child оказывают минимальное стороннее воздействие при использовании простых селекторов.
Рассмотрим HTML и CSS ниже:
List of fruits
- Apples
- Bananas
- Blueberries
- Oranges
- Strawberries
< ! DOCTYPE html > < html lang = "en-US" > < head > < meta charset = "utf-8" > < title > : first - child and : last - child < / title >
< / head > < body > < h2 > List of fruits < / h2 > < ul > < li > Apples < / li > < li > Bananas < / li > < li > Blueberries < / li > < li > Oranges < / li > < li > Strawberries < / li > < / ul > < / body > < / html > |
На скриншоте ниже показан результат.
Заголовок h2 и первый li окрасились в розовый, так как:first-child не привязан к конкретным элементам. Тег h2 – первый ребенок тега body, а li – первый дочерний элемент ul. Но почему оставшиеся элементы li зеленые? Потому что:last-child тоже не привязан к конкретному элементу, а ul является последним дочерним элементом в теге body. По сути, в стилях выше мы прописали *:first-child и *:last-child.
Если добавить к:first-child и:last-child простой селектор, они станут конкретнее. Давайте ограничим нашу выборку только элементами списка. Замените:first-child на li:first-child и:last-child на li:last-child. На скриншоте ниже показан результат.
:nth-child() и:nth-last-child()
Уметь выбирать первый и последний дочерние элементы в документе неплохо. А что если нужно выбрать четные или нечетные элементы? Может, нам нужно выбрать шестой элемент в дереве или применить стили к каждому третьему дочернему элементу. Здесь нам помогут псевдоклассы:nth-child() и:nth-last-child().
Как и:not, :nth-child() и:nth-last-child() также являются функциональными псевдоклассами. Они принимают один аргумент, который должен быть:
ключевым словом odd;
ключевым словом even;
целочисленным значением типа 2 или 8;
аргументом в форме Аn+B , где А – шаг, B – смещение, а n – переменная с положительным целочисленным числом.
Последний аргумент немного сложнее остальных. Разберем его чуть позже.
Чем отличаются:nth-child() и:nth-last-child()? Они отличаются точкой отсчета: :nth-child() считает вперед, а:nth-last-child() – назад. CSS индексы используют натуральные числа и начинаются с 1, а не с 0.
С помощью псевдоклассов:nth-child() и:nth-last-child() удобно создавать чередующиеся узоры. Полосатая таблица – идеальный пример использования. CSS ниже присваивает четным строкам в таблице светлый синевато-серый фон, результат можно посмотреть на скриншоте ниже:
tr:nth-child(even) { background: rgba(96, 125, 139, 0.1); }
tr : nth - child (even ) { background : rgba (96 , 125 , 139 , 0.1 ) ; |
Если переключиться с:nth-child на:nth-last-child, полосы инвертируются, так как отсчет начнется с низа. Смотрите скриншот ниже.
А хотите что-нибудь посложнее, с более сложными аргументами? Давайте создадим документ с 20 элементами, как показано ниже.
С помощью:nth-child() и:nth-last-child() можно выбрать один определенный элемент. Можно выбрать все дочерние элементы после заданной позиции, или можно выбрать элементы с кратностью со смещением. Давайте изменим фон шестого элемента:
Item:nth-child(6) { background: #e91e63; }
Еще раз, А – шаг. Это множитель для n, начинающийся с 1. То есть если А = 3, то 3n выберет третий, шестой и девятый элементы и т.д. Именно это можно наблюдать на скриншоте ниже.
Здесь уже все немного интереснее. С помощью:nth-child() и:nth-last-child() можно выбрать все элементы после заданной точки. Давайте выберем все элементы кроме первых семи:
Item:nth-child(n+8) { background: #e91e63; }
Item : nth - child (n + 8 ) { background : #e91e63; |
Здесь шаг не задан. Как результат, n+8 выбирает все элементы n, начиная с восьмого. Смотрите скриншот ниже.
Замечание: отрицательное смещение
Отрицательные значения и диапазоны также валидны. Запись типа:nth-child(-n+8) инвертирует выборку и выбирает первые восемь элементов.
С помощью смещения и шага можно выбрать каждый третий элемент, начиная с пятого:
Item:nth-child(3n+5) { background: #e91e63; }
Item : nth - child (3n + 5 ) { background : #e91e63; |
Результат.
only-child
Псевдокласс only-child выбирает элемент только в том случае, если он единственный дочерний элемент. Ниже представлено два маркированных списка. В первом один элемент, во втором три:
- Apple
- Orange
- Banana
- Raspberry
< ul > < li > Apple < / li > < / ul > < ul > < li > Orange < / li > < li > Banana < / li > < li > Raspberry < / li > < / ul > |
Селектор li:only-child{color: #9c27b0;} выберет
:empty
С помощью псевдокласса:empty можно выбрать элементы, у которых нет дочерних элементов. Псевдокласс:empty говорит сам за себя (empty от англ. «пустой»). Чтобы попасть в выборку:empty, элемент должен быть абсолютно пустым, не должно быть даже пробелов. То есть попадает в выборку, а нет.
Иногда WYSIWYG редакторы вставляют пустые теги p в ваш контент. С помощью:empty и:not можно делать так, чтобы к этим элементам не применялись стили. Например, p:not(:empty).
Выбор элементов определенного типа по их индексу
Описанные в предыдущем разделе псевдоклассы выбирают элементы, если те занимают определенную позицию в дереве документа. Например, p:nth-last-child(2) выберет все теги p перед последним внутри родительского блока.
В этом разделе мы поговорим о типизированных индексных псевдоклассах. Эти псевдоклассы также выбирают элементы по значению индекса, но выбор ограничен определенным типом. Например, нужно выбрать пятый тег p или четные h2.
Существует пять таких псевдоклассов, имена которых полностью противоположны их нетипизированным коллегам:
nth-last-of-type()
Грань между ними и дочерними индексными псевдоклассами тонка. Запись p:nth-child(5) находит только пятый тег p, а запись p:nth-of-type(5) находит все теги p и вычленяет среди них пятый.
Давайте создадим другой документ. В нем также 20 элементов, только некоторые — это теги p, а другие – div. Теги p со скругленными углами, смотрите скриншот ниже.