Псевдоклассы: :hover, :focus, :nth-child и другие

Псевдоклассы - это часть селектора после двоеточия, которая описывает не тег и не класс в разметке, а состояние или положение элемента: наведён ли на него курсор, в фокусе ли он, каким по счёту стоит среди соседей. В HTML для этого ничего добавлять не нужно - псевдокласс сам следит за нужным условием.

Попробуй прямо в этом окне: наведи курсор на кнопку - она сразу поменяет цвет, а как только уберёшь курсор, вернётся обратно, без единой строчки JavaScript. Кликни в поле ввода - вокруг появится рамка, это работает :focus. А среди пунктов списка жирным окажется именно "Второй" - это ровно второй элемент среди соседей, к которому применилось правило li:nth-child(2).

:hover - при наведении курсора

Псевдокласс :hover применяет стиль, пока указатель мыши находится над элементом. Раньше он работал только со ссылками, но сейчас - с любым элементом на странице: кнопкой, картинкой, целым блоком.

button:hover { background: dodgerblue; } - кнопка меняет цвет, пока курсор над ней, и без всякого JavaScript.

.menu-item:hover .submenu { display: block; } как единственный способ показать важное меню - на сенсорных экранах :hover срабатывает непредсказуемо: может не сработать вообще, сработать ненадолго после касания или "залипнуть" после того, как палец уже убрали.

:focus - когда элемент в фокусе

Псевдокласс :focus применяется, пока элемент находится в фокусе - то есть готов принимать ввод. Элемент попадает в фокус кликом мыши или клавишей Tab, что особенно важно для тех, кто пользуется сайтом с клавиатуры, а не мышью.

input:focus { outline: 3px solid tomato; } - явно показывает, какое поле сейчас активно.

*:focus { outline: none; } без какой-либо замены - убирает стандартную рамку фокуса у браузера, и человек, который перемещается по странице клавишей Tab, перестаёт видеть, на каком элементе он сейчас находится.

:nth-child() - по порядковому номеру

Псевдокласс :nth-child(N) выбирает элемент, который стоит N-м по счёту СРЕДИ ВСЕХ соседних элементов у одного родителя - независимо от тега. Вместо конкретного числа можно писать odd (нечётные) или even (чётные) - удобно, например, для полосатых таблиц.

tr:nth-child(odd) { background: #eee; } - классическая "зебра" для строк таблицы: подсвечивает нечётные строки.

p:nth-child(2), ожидая, что это "второй абзац" - на самом деле nth-child считает ВСЕХ соседей подряд, а не только абзацы. Если перед абзацами стоит заголовок, вторым ребёнком окажется первый же абзац, а не второй. Чтобы выбрать именно "второй элемент именно этого тега", нужен другой псевдокласс - :nth-of-type(2).

И другие полезные псевдоклассы

Кроме трёх разобранных выше, часто пригождаются ещё несколько.

li:first-child { margin-top: 0; } - выбирает самый первый элемент среди соседей, удобно убрать лишний отступ у первого пункта списка.

li:last-child { border-bottom: none; } - выбирает самый последний элемент, например чтобы убрать нижнюю границу у последней строки списка.

li:not(.active) { opacity: 0.6; } - выбирает всё, КРОМЕ элементов с классом active, - удобно, когда проще описать исключение, чем перечислять всё остальное.

Из истории Псевдоклассы тоже собирались по частям добавлений в течение полутора десятков лет. В CSS1 1996 года были только три псевдокласса, и только для ссылок: A:link, A:visited и A:active. В CSS2, ставшей рекомендацией W3C 12 мая 1998 года, добавили :hover и :focus - и, что важно, их (вместе с :active) обобщили на ЛЮБОЙ элемент, а не только на ссылки, плюс появился :first-child. А вот :nth-child(), :last-child и :not() определили ещё позже - только в CSS Selectors Level 3, ставшей рекомендацией W3C 29 сентября 2011 года. Источники: w3.org - спецификация CSS1, 1996, w3.org - селекторы CSS2, 1998, w3.org - Selectors Level 3, 2011.

Частые ошибки новичков

ОшибкаЧто происходитКак исправить
Делать важный контент доступным только через :hover На сенсорных экранах у :hover нет надёжного эквивалента - контент может стать неудобным или вовсе недоступным Дублировать доступ к важному контенту кликом/тапом, а не только наведением
Писать outline: none; для :focus без какой-либо замены Пользователь, который ходит по странице клавишей Tab, перестаёт видеть, на каком элементе он находится сейчас Если стандартная рамка не устраивает по дизайну, заменить её своей - но не убирать совсем
Путать :nth-child(N) с "N-м элементом этого же тега" :nth-child(N) считает ВСЕХ соседей подряд, независимо от тега - легко ошибиться в расчёте, если среди соседей есть элементы другого типа Для "N-й элемент именно такого тега" использовать :nth-of-type(N)
Думать, что :hover/:focus/:active работают только со ссылками Ещё с CSS2 1998 года они применяются к любому элементу - кнопке, картинке, целому блоку Смело использовать эти псевдоклассы с любыми элементами, не только с <a>

Шпаргалка

ПсевдоклассКогда срабатывает
:hoverПока курсор наведён на элемент
:focusПока элемент в фокусе - клик или клавиша Tab
:nth-child(N)N-й по счёту среди ВСЕХ соседей, независимо от тега
:nth-child(odd/even)Все нечётные/чётные по счёту соседи - удобно для "зебры"
:first-child / :last-childСамый первый / самый последний среди соседей
:not(селектор)Все элементы, КРОМЕ подходящих под указанный селектор

Коротко: отвечаем на вопросы

В чём разница между :nth-child и :nth-of-type?

:nth-child(2) выбирает элемент, если он одновременно и нужный тег, и второй по счёту среди ВСЕХ соседей. :nth-of-type(2) считает только элементы того же тега и не сбивается, если рядом есть элементы другого типа - например, второй именно <p>, даже если перед абзацами есть заголовок.

Почему :hover плохо работает на телефоне?

На сенсорных экранах нет наведения курсора в привычном смысле - в зависимости от браузера :hover может вообще не сработать, сработать ненадолго после касания или "залипнуть" уже после того, как палец убрали. Поэтому важный контент нельзя делать доступным только через :hover.

Можно ли комбинировать псевдокласс с обычным селектором, например с классом?

Да, псевдокласс просто дописывается через двоеточие сразу после остальной части селектора: .btn:hover сработает только для элемента с классом btn, когда на него навели курсор.

Обязательно ли убирать рамку фокуса, если она не нравится по дизайну?

Нет, и лучше не убирать совсем - если стандартная рамка браузера не подходит по стилю, её стоит заменить своей собственной через :focus, а не просто спрятать через outline: none.

Категория
css
Поделиться в социальных сетях

Отправить комментарий

0 Комментарии

Отправить комментарий (0)

#buttons=(Хорошо) #days=(20)

Мы используем файлы cookie для улучшения работы сайта. Подробнее
Хорошо
×