Menu

Псевдоклассы CSS: nth-child, not, first-child, focus

Псевдоклассы выбирают элементы по позиции или состоянию: :nth-child(), :first-child, :not(), :focus, :checked, :has() и другие. Разберем синтаксис, формулу an+b с живым тестером и разницу между nth-child и nth-of-type.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

Что такое псевдокласс

Псевдокласс это ключевое слово после двоеточия, которое выбирает элементы по их позиции в документе или по состоянию. Его присоединяют к обычному селектору: li:first-child, input:focus, a:hover.

Псевдоклассам состояния ссылок и мыши (:hover, :active, :visited) посвящена отдельная страница, hover в CSS.

:nth-child() и формула an+b

:nth-child() принимает число, ключевое слово или формулу an+b. Браузер перебирает n = 0, 1, 2, ... и выбирает каждую позицию, которую дает формула (позиции начинаются с 1).

ФормулаВыбирает позицииЗначение
33Третий дочерний элемент
odd или 2n+11, 3, 5, ...Нечетные строки
even или 2n2, 4, 6, ...Четные строки
3n3, 6, 9, ...Каждый третий
n+44, 5, 6, ...Четвертый и следующие
-n+31, 2, 3Первые три
3n+11, 4, 7, ...Каждый третий, начиная с первого

Введите формулу и посмотрите, какие пункты подходят:

Попробуйте odd, even, 4, n+7, -n+5 и 2n+3. Невалидная формула ничего не выбирает.

Близнец, считающий с конца, это :nth-last-child(): li:nth-last-child(-n+2) выбирает два последних пункта.

nth-child и nth-of-type

:nth-child() считает все соседние элементы, какой бы ни был тег, и только потом проверяет остальную часть селектора. :nth-of-type() считает только соседей с тем же тегом. Разница видна, как только соседи смешаны:

Такие же пары есть для краев: :first-child / :first-of-type, :last-child / :last-of-type, :only-child / :only-of-type.

:not(), :is() и :where()

ПсевдоклассПримерВыбирает
:not(X)li:not(.done)Элементы, которые не подходят под X
:is(X, Y):is(h1, h2, h3) aЭлементы, подходящие под любой из списка
:where(X, Y):where(ul, ol) liТо же, что :is(), с нулевой специфичностью
:has(X)li:has(> input:checked)Элементы, внутри которых есть совпадение с X

:not() используется каждый день, например чтобы поставить разделитель между пунктами, но не после последнего:

Псевдоклассы состояния: focus, checked, disabled, invalid

ПсевдоклассВыбирает
:focusЭлемент, на котором фокус клавиатуры или мыши
:focus-visibleЭлемент в фокусе, когда браузер решает показать рамку (обычно при фокусе с клавиатуры)
:focus-withinЭлемент, внутри которого находится элемент в фокусе
:checkedОтмеченный чекбокс, радиокнопку или выбранный <option>
:disabled / :enabledЭлементы форм, которые отключены (или нет)
:required / :optionalПоля с required или без него
:invalid / :validПоля, значение которых не проходит или проходит проверку
:user-invalidНевалидные, но только после взаимодействия пользователя с полем
:placeholder-shownПоле, в котором сейчас виден placeholder
:emptyЭлемент без дочерних узлов, даже без текста
:targetЭлемент, id которого совпадает с #fragment в URL

Кликните в поле email: его подпись станет синей благодаря :focus-within. Введите что-то, что не является email, и выйдите из поля: :user-invalid сделает рамку янтарной. Обычный :invalid пометил бы пустое обязательное поле янтарным еще до того, как вы к нему прикоснулись.

Что бы вы ни делали с :focus, оставляйте видимый стиль фокуса. Если убрать outline без замены, пользователи клавиатуры не увидят, где находятся.

:has(), селектор родителя

:has() выбирает элемент по тому, что в нем находится. Это давно ожидаемый «селектор родителя», и он работает в актуальных Chrome, Firefox и Safari.

Выберите другой тариф: вся карточка следует за радиокнопкой, без JavaScript.

Частые ошибки

  • Пробел перед двоеточием. li :first-child означает «первый дочерний элемент внутри li». Пишите li:first-child.
  • Ожидание, что p:nth-child(1) значит «первый p». Он значит «первый дочерний элемент, если это p». Для первого p используйте :first-of-type.
  • Счет с 0. Позиции начинаются с 1: :nth-child(0) ничего не выбирает.
  • Удаление рамки фокуса. :focus { outline: none } без замены ломает навигацию с клавиатуры.
  • Путаница : и ::. :before это старое написание псевдоэлемента ::before; псевдоклассы всегда пишутся с одним двоеточием.

Часто задаваемые вопросы

Что такое псевдокласс в CSS?

Ключевое слово после двоеточия, которое выбирает элементы по состоянию или позиции, а не по имени, например a:hover, li:first-child или input:focus. Его добавляют к обычному селектору, и большинство псевдоклассов в специфичности считаются как класс (:where() считается нулем).

Как работает nth-child в CSS?

:nth-child(an+b) выбирает элементы, чья позиция среди соседей равна a×n+b при n = 0, 1, 2 и так далее, счет с 1. :nth-child(3) это третий дочерний элемент, :nth-child(odd) или 2n+1 каждый нечетный, а :nth-child(n+4) четвертый и все следующие.

Чем nth-child отличается от nth-of-type?

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

Как использовать :not() в CSS?

Поместите в скобки селектор, который нужно исключить: li:not(.done) выбирает все пункты списка без класса done. Он принимает и список: input:not([type="checkbox"], [type="radio"]).

Чем псевдокласс отличается от псевдоэлемента?

Псевдокласс (одно двоеточие, :hover) выбирает целый существующий элемент в каком-то состоянии. Псевдоэлемент (два двоеточия, ::before) обращается к части элемента или создает генерируемое содержимое.

Coddy programming languages illustration

Учитесь программировать с Coddy

НАЧАТЬ