Урок 41. Теория: Псевдоклассы и псевдоэлементы

📁 Раздел: Современный CSS ⏱️ Время изучения: ~80 мин 🎯 Сложность: Средняя
#hover #focus #active #nth-child #first-child #checked #not #is #where #before #after #first-line #placeholder #selection

⚡ Кратко

Псевдокласс (одно двоеточие :) выбирает элемент по его состоянию или положению: наведён ли курсор (:hover), в фокусе ли он (:focus), какой он по счёту (:nth-child), отметили ли чекбокс (:checked). Сам HTML при этом не меняется.

Псевдоэлемент (два двоеточия ::) дорисовывает часть, которой в HTML нет: иконку или галочку через ::before/::after + content, первую строку (::first-line), серый текст-подсказку (::placeholder), выделенный мышью фрагмент (::selection).

  • Состояние не вечно: убрал курсор — :hover исчез.
  • Для клавиатуры нужен видимый :focus/:focus-visible, не только :hover.
  • ::before/::after без content не появятся вовсе.

Главная идея

До сих пор мы выбирали элементы по тегу, классу или id — то есть по тому, что написано в HTML. Псевдоклассы и псевдоэлементы добавляют два новых измерения: выбор по текущему состоянию элемента и стилизацию частей, которых в разметке нет. Это позволяет делать интерактивный, «живой» интерфейс одним только CSS, не добавляя ни строчки JavaScript и ни одного лишнего тега.

Псевдокласс — это реакция на состояние. Представь дверь с подсветкой: пока к ней не подошли — она обычная, поднёс руку (:hover) — загорелась, открыл (:active) — мигнула. Дверь физически та же, меняется лишь её состояние, и подсветка реагирует автоматически.

Псевдоэлемент — это дорисованная деталь. Как наклейка «NEW» в углу товара на витрине: самого товара (HTML) она не часть, её приклеили поверх для красоты. ::before/::after — такие же наклейки, которые CSS «дорисовывает» в начало или конец элемента.

Один знак двоеточия или два?

Синтаксически их легко перепутать, но разница принципиальная: : — псевдокласс (состояние/позиция уже существующего элемента), :: — псевдоэлемент (новая виртуальная сущность).

Один элемент <li> и два псевдоэлемента ::before дорисован <li> … </li> реальный HTML ::after дорисован ::before и ::after живут ВНУТРИ элемента, по краям его содержимого
Псевдоэлементы ::before/::after добавляются как первый и последний «ребёнок» внутри элемента — их нет в HTML, их создаёт CSS.

Псевдоклассы состояния: :hover, :focus, :active

Эти три описывают, что происходит с элементом прямо сейчас: :hover — на элемент наведён курсор; :active — элемент в момент нажатия (кнопка мыши зажата); :focus — элемент получил фокус (клик по полю или переход по Tab). Правильный порядок объявления для ссылок — LVHA (:link, :visited, :hover, :active), иначе более позднее правило перебьёт более раннее.

Доступность: :hover недоступен с клавиатуры и на тач-экранах. Любое интерактивное состояние дублируйте видимым :focus или :focus-visible — иначе пользователь, идущий по Tab, не поймёт, где находится.

Структурные псевдоклассы: :nth-child, :first/last-child, :not, :checked

:nth-child() выбирает элемент по его номеру среди соседей: even — чётные, odd — нечётные, 3n — каждый третий. Так делают «зебру» в таблицах одним правилом. :first-child/:last-child — первый и последний в группе. :not(...) исключает: a:not(.active) — все ссылки, кроме активной. :checked срабатывает на отмеченном чекбоксе или радио — позволяет менять вид интерфейса без JavaScript.

📄 lesson-41/styles.css
/* зебра: подсветить каждую чётную строку */
.lesson-list li:nth-child(even) {
  background: #f1f5f9;
}

/* все ссылки, кроме активной — без подчёркивания */
.lesson-list a:not(.active) {
  text-decoration: none;
}

/* отмеченный чекбокс делает метку зелёной */
input:checked + label {
  color: #16a34a;
}

Псевдоэлементы: ::before, ::after, ::placeholder, ::selection

::before и ::after создают виртуальный элемент в начале/конце содержимого. Они не появятся без свойства content — даже пустого (content: ''). Идеальны для декора: иконок, стрелок, разделительных линий, бейджей. ::placeholder стилизует текст-подсказку в полях ввода, ::first-line — только первую строку абзаца, а ::selection — тот фрагмент, который пользователь выделил мышью.

Важное правило доступности: текст из content в ::before/::after — декоративный. Не помещайте туда смысловой текст (его не увидят скринридеры и нельзя выделить/скопировать). Содержание — в HTML, украшения — в псевдоэлементах.

Группировка: :is() и :where()

Оба сворачивают длинные перечисления селекторов: вместо h1, h2, h3 можно написать :is(h1, h2, h3). Разница — в специфичности: :is() берёт специфичность самого «сильного» аргумента, а :where() всегда имеет нулевую специфичность, поэтому его правила легко переопределить. :where() идеален для базовых стилей-«основы», которые потом будут перекрываться.

⚠️ Проверить по документации: точные правила вычисления специфичности :is()/:where() и поддержку в целевых браузерах — на MDN :is() и MDN :where().

Частая ошибка

Самая распространённая — написать ::before и забыть content: псевдоэлемент просто не отрисуется, и автор долго ищет «несуществующий» баг. Вторая — стилизовать только :hover, забыв :focus: на десктопе всё работает, но с клавиатуры интерфейс «слепой».

Навигация