CSS псевдо-классы: стилизация элементов на основе их индексов

Выбор элементов по индексу
В CSS предусмотрены селекторы для выбора элемента на основе его позиции в дереве. Это так называемые дочерние псевдо-классы, они зависят только от позиции или порядкового номера элемента, а не от типа, атрибутов или ID. Вот пять из них:
- :first-child
- :last-child
- :only-child
- :nth-child()
- :nth-last-child()
:first-child и :last-child
Как вы уже, наверное, догадались из названия, псевдо-классы :first-child
и :last-child
позволяют выбрать первый или последний дочерний элемент. Так же как и в других псевдо-классах, влияние :first-child
и :last-child
зависит от ограничивающего селектора.
Давайте рассмотрим, показанный ниже, HTML и CSS:
<h2>List of fruits</h2>
<ul>
<li>Apples</li>
<li>Bananas</li>
<li>Blueberries</li>
<li>Oranges</li>
<li>Strawberries</li>
</ul>
:first-child {
color: #e91e63;
}
:last-child {
color: #4caf50;
}
В браузере это будет выглядеть вот так:
Поскольку :first-child
не ограничен, то и h2
и первый li
стали розовыми. h2
– первый дочерний элемент body
, а li
– первый дочерний элемент ul
. Но почему все остальные li
стали зелеными? Так как :last-child
тоже не ограничен, то ul
– последний дочерний элемент body
. По сути это то же самое, что *:first-child
и *:last-child
.
Если мы добавим к :first-child
и :last-child
простой селектор, все обретет совершенно другой смысл. Давайте ограничимся элементами списка. Поменяем :first-child
на li:first-chil
, а :last-child
на li:last-child
. Результат показан на изображении ниже.
:nth-child() и :nth-last-child()
Возможность выбрать первый и последний дочерний элемент – это хорошо. Но что, если нужно выбрать парные или не парные элементы? Возможно, нам нужен 6й элемент дерева или каждый третий. В этом помогут :nth-child()
и :nth-last-child()
.
Так же как и :not()
, :nth-child()
и :nth-last-child()
– это функциональные псевдо-классы. Они принимают аргумент, который может быть одним из следующих вариантов:
- Ключевое слово
odd
- Ключевое слово
even
- Целое число, например, 2 или 8
- Аргумент в виде
An+B
, где А – это шаговый интервал, В – это смещение, а n – переменная, представляющая собой целое число.
Какая разница между :nth-child()
и :nth-last-child()
? Разница в точке отсчета: :nth-child()
считает с начала, а :nth-last-child()
с конца. Отсчет начинается не с нуля, а с единицы.
И :nth-child()
и :nth-last-child()
полезны в создании поочередных шаблонов. Создание полосатой таблицы – отличный пример. CSS код ниже позволяет парным строкам таблицы задать светло-серый цвет фона, результат показан ниже:
tr:nth-child(even) {
background: rgba(96, 125, 139, 0.1);
}
Поменяйте :nth-child
на :nth-last-child
и все перевернется, так как отсчет начнется снизу.
Как на счет более сложных аргументов? Начнем с документа, который содержит 20 элементов.
С помощью :nth-child()
и :nth-last-child()
мы можем выбрать один элемент на определенной позиции. Выбрать все дочерние элементы после определенной позиции или выбрать несколько, используя смещение. Давайте поменяем цвет 6го элемента:
.item:nth-child(6) {
background: #e91e63;
}
А что, если мы хотим выбрать каждый третий элемент? В этом поможет синтаксис An+B
:
.item:nth-child(3n) {
background: #e91e63;
}
Напомню, А – это шаговый интервал. Это как множитель для n, который начинается с 1. Таким образом, если А=3, то 3n выберет 3й, 6й, 9й и тд элементы.
Используя :nth-child()
и :nth-last-child()
, можно выбрать все элементы после определенной позиции. Давайте попробуем выбрать все элементы, кроме первых семи:
.item:nth-child(n+8) {
background: #e91e63;
}
В аргументе нет шагового интервала. В результате, n+8
выбирает все элементы, начиная с восьмого, как показано ниже.
Негативное смещение
Негативные значения тоже валидны. Использование :nth-child(-n+8)
инвертирует выборку и выберет первые восемь элементов.
Также мы можем использовать смещение и шаговое значение, чтобы выбрать каждый третий элемент, начиная с пятого:
.item:nth-child(3n+5) {
background: #e91e63;
}
Результат выборки показан ниже.
:only-child
Псевдо-класс :only-child
выбирает элемент только в том случае, если он единственный дочерний элемент. Ниже два списка, в первом один дочерний элемент, а во втором – три:
<ul>
<li>Apple</li>
</ul>
<ul>
<li>Orange</li>
<li>Banana</li>
<li>Raspberry</li>
</ul>
Правило li:only-child{color: #9c27b0;}
выберет элемент Apple, поскольку он единственный дочерний элемент списка. Ни один из элементов второго списка не выбран, потому что в нем три дочерних элемента.
:empty
Также, используя псевдо-класс :empty
, можно выбрать элементы, у которых нет дочерних блоков. Псевдо-класс :empty
выбирает пустые элементы, то есть внутри элемента не должно быть ничего, даже пробела. Другими словами, <p></p>
будет выбран, а <p> </p>
нет.
Иногда редактор WYSIWYG (What You See Is What You Get) вставляет в контент пустые теги p
. Можно использовать :empty
в комбинации с псевдо-классом :not()
, чтобы к пустым элементам не применялись стили. Например, p:not(:empty)
.
Выбор элементов определенного типа по индексу
Псевдо-классы рассмотренные в предыдущей секции выбирали элементы, занимающие определенную позицию в дереве. Например, p:nth-last-child(2)
выбирает предпоследний элемент p.
В этой секции мы рассмотрим псевдо-классы связанные с типом. Эти псевдо-классы тоже выбирают элементы на основе их индекса, но выборка ограничивается типом элементов.
Ниже 5 таких псевдо-классов с именами, напоминающими имена своих нетипизированных коллег:
- :first-of-type
- :last-of-type
- :only-of-type
- :nth-of-type()
- :nth-last-of-type()
Разница между этими псевдо-классами и предыдущими очень тонкая. Если p:nth-child(5)
выберет пятый элемент, если он p
, то p:nth-of-type(5)
выберет все элементы p
, если пятым из них окажется p
.
Давайте начнем с небольшого изменения документа. В нем все так же 20 элементов, но теперь среди них есть p
и div
. Элементы p
имеют скругленные углы.
Использование :first-of-type, :last-of-type и :only-type
С помощью :first-of-type
мы можем выбрать первый элемент, который соответствует селектору. Давайте закрасим фон первого элемента p
в зеленый цвет:
p:first-of-type {
background: #cddc39;
}
Псевдо-элемент :last-of-type
работает аналогично, выбирая последний элемент подходящего типа. А вот :only-of-type
выберет элемент только в том случае, если он будет единственным дочерним элементом такого же типа, демонстрация ниже.
Давайте рассмотрим еще один пример использования :first-of-type
, но в этот раз с псевдо-элементом. Псевдо-элемент ::first-letter
выделяет заглавную букву каждого элемента, к которому применяется. Давайте установим ограничение, чтобы ::first-letter
работал только с первым абзацем:
p:first-of-type::first-letter {
font: bold italic 3em / .5 serif;
color: #3f51b5;
}
Как показано на изображении ниже, первый параграф получил заглавную букву, не смотря на то, что он идет после заголовка.
Использование :nth-of-type и :nth-last-of-type
:nth-of-type()
и :nth-last-of-type()
тоже функциональные псевдо-классы. Они принимают такие же аргументы как и :nth-child()
и :nth-last-child()
. Но так же как и в случаи с :first-of-type
и :last-of-type
, индексы применяются только к элементам того же типа. К примеру, чтобы выбрать все нечетные элементы p
, мы можем использовать ключевое слово odd
:
p:nth-of-type(odd) {
background: #cddc39;
color: #121212;
}
Аналогично, использование :nth-last-of-type(even)
выберет все четные элементы p
, но отсчет начнется с последнего элемента данного типа – в данном случаи, с 18го элемента p
.