Псевдоклассы CSS — :hover, :focus, :active и другие

Псевдоклассы задают стили элементу в определённом состоянии: при наведении курсора, в фокусе, при нажатии, или по позиции в DOM. Позволяют реагировать на действия пользователя без JavaScript.

Вся рубрика CSS: уроки, примеры и справочник по стилям

Псевдоклассы взаимодействия

/* :hover — при наведении мыши */
a:hover     { color: #2563eb; text-decoration: underline; }
button:hover { background: #1d4ed8; transform: translateY(-2px); }
.card:hover  { box-shadow: 0 8px 24px rgba(0,0,0,0.15); }

/* :active — в момент нажатия (пока удерживается клик) */
button:active       { transform: scale(0.97); }
a:active            { color: #1d4ed8; }
.btn:active         { box-shadow: none; }

/* :focus — когда элемент в фокусе (клик или Tab) */
input:focus {
  outline: none;
  border-color: #2563eb;
  box-shadow: 0 0 0 3px rgba(37,99,235,0.15);
}
a:focus { outline: 2px solid #2563eb; outline-offset: 2px; }

/* :focus-visible — фокус ТОЛЬКО при клавиатурной навигации */
/* Не срабатывает при клике мышью — более аккуратно чем :focus */
button:focus-visible {
  outline: 2px solid #2563eb;
  outline-offset: 3px;
}

/* :focus-within — если фокус у любого потомка */
.form-group:focus-within label {
  color: #2563eb;  /* метка синеет когда input в фокусе */
}

/* :visited — посещённые ссылки */
a:visited { color: #7c3aed; }

/* :link — не посещённые ссылки */
a:link { color: #2563eb; }

/* Правильный порядок для ссылок (LVHA) */
a:link    { color: blue; }
a:visited { color: purple; }
a:hover   { color: red; }
a:active  { color: darkred; }
CSS hover focus active focus-visible состояния кнопки карточки и input
Интерактивные псевдоклассы помогают интерфейсу отвечать на действия пользователя: наведение, фокус и нажатие.

Структурные псевдоклассы

/* :first-child — первый ребёнок родителя */
li:first-child  { font-weight: bold; }
p:first-child   { font-size: 1.1rem; }

/* :last-child — последний ребёнок */
li:last-child   { border-bottom: none; margin-bottom: 0; }
td:last-child   { text-align: right; }

/* :nth-child(n) — по порядковому номеру */
li:nth-child(1)    { color: gold; }     /* первый */
li:nth-child(2)    { color: silver; }   /* второй */
tr:nth-child(even) { background: #f9fafb; } /* чётные — зебра */
tr:nth-child(odd)  { background: white; }   /* нечётные */
li:nth-child(3n)   { /* каждый третий: 3, 6, 9... */ }
li:nth-child(3n+1) { /* 1, 4, 7, 10... */ }
li:nth-child(-n+3) { /* первые три */ }

/* :nth-last-child(n) — считает с конца */
li:nth-last-child(1) { /* последний */ }
li:nth-last-child(2) { /* предпоследний */ }

/* :only-child — единственный ребёнок */
p:only-child { font-size: 1.2em; text-align: center; }

/* :nth-of-type — по порядку среди одинаковых тегов */
p:nth-of-type(1)  { font-size: 1.15rem; font-weight: 500; }
img:nth-of-type(2) { float: right; }

/* :first-of-type, :last-of-type */
h2:first-of-type  { margin-top: 0; }
img:last-of-type  { margin-bottom: 0; }

/* :not() — исключение (отрицание) */
li:not(:last-child)      { border-bottom: 1px solid #e5e7eb; }
button:not([disabled])   { cursor: pointer; }
p:not(.lead):not(.note)  { color: #4b5563; }
input:not([type="submit"]) { border: 1px solid #d1d5db; }
Структурные псевдоклассы CSS first child last child nth child not на списке и таблице
Структурные псевдоклассы выбирают элемент не по классу, а по его позиции среди соседей.

Псевдоклассы форм

/* :checked — выбран чекбокс или радио */
input[type="checkbox"]:checked + label {
  color: #2563eb;
  font-weight: 600;
}

/* Кастомный чекбокс */
.custom-checkbox input:checked + span::before {
  background: #2563eb;
  content: '✓';
  color: white;
}

/* :disabled — отключённый элемент */
button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}
input:disabled {
  background: #f3f4f6;
  color: #9ca3af;
}

/* :enabled — активный (противоположность disabled) */
input:enabled:hover { border-color: #93c5fd; }

/* :valid / :invalid — встроенная валидация */
input:valid   { border-color: #16a34a; }
input:invalid { border-color: #dc2626; }

/* Показывать ошибку только после взаимодействия */
input:invalid:not(:placeholder-shown) {
  border-color: #dc2626;
}

/* :required — обязательное поле */
input:required {
  border-left: 3px solid #dc2626;
}
label:has(+ input:required)::after {
  content: ' *';
  color: #dc2626;
}

/* :optional — необязательное поле */
input:optional { border-left: 3px solid #e5e7eb; }

/* :placeholder-shown — placeholder ещё виден (поле пустое) */
input:placeholder-shown { background: #fafafa; }
input:not(:placeholder-shown) { background: white; }

/* :empty — элемент без содержимого */
.error-message:empty { display: none; }
.badge:empty         { display: none; }
Псевдоклассы форм CSS checked disabled valid invalid required placeholder shown
Формы особенно выигрывают от псевдоклассов: пользователь сразу видит выбранные, отключённые и ошибочные поля.

:has() — родительский псевдокласс

:has() — самый мощный псевдокласс, добавленный в CSS. Позволяет стилизовать элемент на основе его потомков. Работает во всех современных браузерах (Chrome 105+, Firefox 121+, Safari 15.4+).

/* Карточка с картинкой — убрать внутренние отступы */
.card:has(img) { padding: 0; }
.card:has(img) .card-body { padding: 16px; }

/* Форма с невалидными полями — кнопку затемнить */
form:has(input:invalid) button[type="submit"] {
  opacity: 0.5;
  pointer-events: none;
}

/* Параграф после заголовка */
h2:has(+ p) { margin-bottom: 4px; }

/* Список без элементов — скрыть */
ul:not(:has(li)) { display: none; }

/* Навигация с активным пунктом */
nav:has(.nav-item.active) { background: #1e293b; }

/* Метка рядом с обязательным полем */
label:has(+ input:required) {
  font-weight: 600;
}
label:has(+ input:required)::after {
  content: ' *';
  color: red;
}

/* Раздел с тёмным фоном — сделать текст белым */
section:has(.dark-bg) { color: white; }
Псевдокласс CSS has стилизует родителя по потомку card has img form has invalid nav has active
:has() позволяет писать правила от родителя: например, затемнить кнопку, если внутри формы есть invalid-поле.

Практические паттерны

/* 1. Полосатая таблица */
table tbody tr:nth-child(even) {
  background: #f9fafb;
}
table tbody tr:hover {
  background: #eff6ff;
  cursor: pointer;
}

/* 2. Навигация — разделитель между пунктами */
.nav-item:not(:last-child) {
  border-right: 1px solid rgba(255,255,255,0.2);
}

/* 3. Аккордеон на чистом CSS */
.accordion-input { display: none; }

.accordion-input:checked + .accordion-label {
  background: #eff6ff;
  color: #2563eb;
}
.accordion-input:checked ~ .accordion-content {
  display: block;
}
.accordion-content { display: none; }

/* 4. Красивый focus-ring */
:focus-visible {
  outline: 2px solid #2563eb;
  outline-offset: 2px;
  border-radius: 4px;
}
/* Убирает outline для мышиных кликов, сохраняет для клавиатуры */

/* 5. Стилизация placeholder */
input::placeholder { color: #9ca3af; font-style: italic; }
input::-webkit-input-placeholder { color: #9ca3af; }

/* 6. Первый параграф статьи */
article p:first-of-type {
  font-size: 1.1rem;
  color: #374151;
  line-height: 1.7;
}
Практические паттерны CSS псевдоклассов таблица зебра accordion checked focus visible nav not last child
Псевдоклассы полезнее всего в практических мелочах: таблицы, меню, аккордеоны и доступный фокус.

Полная таблица псевдоклассов

ПсевдоклассОписание
:hoverПри наведении мыши
:activeВ момент нажатия
:focusВ фокусе
:focus-visibleВ фокусе от клавиатуры
:focus-withinФокус у любого потомка
:visitedПосещённая ссылка
:linkНепосещённая ссылка
:checkedВыбран (чекбокс/радио)
:disabledОтключён
:enabledАктивен
:validЗначение прошло валидацию
:invalidЗначение не прошло
:requiredОбязательное поле
:optionalНеобязательное поле
:placeholder-shownПоле пустое (виден placeholder)
:emptyНет содержимого
:first-childПервый ребёнок
:last-childПоследний ребёнок
:nth-child(n)N-й ребёнок
:nth-last-child(n)N-й с конца
:only-childЕдинственный ребёнок
:first-of-typeПервый такого тега
:last-of-typeПоследний такого тега
:nth-of-type(n)N-й такого тега
:not(selector)Не соответствует
:is(selector)Группировка
:where(selector)Группировка (нулевая специфичность)
:has(selector)Содержит потомка
Шпаргалка CSS псевдоклассов hover focus checked disabled nth child not has is where
Удобно учить псевдоклассы не списком, а группами: состояния, структура, формы и логические условия.

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

:nth-child и :nth-of-type — в чём разница?

:nth-child считает всех детей родителя подряд. :nth-of-type считает только детей данного типа тега. Пример: p:nth-child(2) применится к <p> только если он второй ребёнок родителя (не важно какого типа первый). p:nth-of-type(2) применится ко второму <p> среди всех <p> внутри родителя — независимо от других тегов.

Сравнение CSS nth child и nth of type на структуре HTML с div h2 p p
:nth-child смотрит на общий номер ребёнка, а :nth-of-type считает только элементы выбранного тега.

Как стилизовать placeholder в input?

Используй псевдоэлемент ::placeholder (два двоеточия): input::placeholder { color: #9ca3af; }. Для максимальной совместимости можно добавить вендорный префикс: ::-webkit-input-placeholder. Обрати внимание: не все стили работают с placeholder — поддерживаются color, font-size, font-style, opacity, но не background или padding.

Как сделать hover только на устройствах с мышью?

Используй медиазапрос @media (hover: hover) — он проверяет есть ли у устройства указатель с hover (мышь). На тачскрине hover нет, поэтому там :hover срабатывает при тапе и не убирается — это плохой UX. Правильный подход:

/* Только для устройств с мышью */
@media (hover: hover) and (pointer: fine) {
  .card:hover {
    transform: translateY(-4px);
    box-shadow: 0 8px 24px rgba(0,0,0,0.15);
  }
}
CSS hover только для мыши через media hover hover pointer fine без тачскрина
Hover-эффекты лучше включать только там, где есть настоящий hover: на тачскринах они часто ведут себя неожиданно.

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x