Псевдоклассы и псевдоэлементы в CSS: практическое руководство с примерами
Этот материал — практическое руководство по запросу «псевдоклассы и псевдоэлементы в CSS с примерами». Разберём, чем они отличаются, как применять их в реальной вёрстке и какие ошибки чаще всего встречаются у новичков.
Псевдоклассы vs псевдоэлементы
- Псевдоклассы (одна двоеточие, например
:hover) описывают состояние уже существующего элемента: наведение, фокус, выбранность, соответствие условию. - Псевдоэлементы (две двоеточия, например
::before) создают «виртуальные» части элемента: декоративные вставки, первую букву, маркеры списков и т. п.
Часто используемые псевдоклассы
:hover, :focus, :focus-visible, :active
Базовые состояния интерактивных элементов. Используйте :focus-visible для доступности, чтобы включать подсветку фокуса только при клавиатурной навигации.
.btn {
background: #2d6cdf;
color: #fff;
border: none;
padding: 10px 16px;
border-radius: 8px;
transition: background .2s, transform .05s;
}
.btn:hover { background: #2457b5; }
.btn:active { transform: translateY(1px); }
.btn:focus-visible {
outline: 3px solid #ffcc00;
outline-offset: 2px;
}
.btn:disabled {
opacity: .55;
pointer-events: none;
}
:checked, :disabled, :target
:checked— состояние переключателей (checkbox, radio).:disabled— отключённые поля и кнопки.:target— элемент, на который указывает якорь из URL (например,#faq1). Полезно для подсветки и плавного перехода к разделу.
/* Подсветка блока, к которому перешли по якорю */
:target {
outline: 2px solid #ffcc00;
animation: targetFlash 2s ease-out;
}
@keyframes targetFlash {
from { background: rgba(255,204,0,.25); }
to { background: transparent; }
}
/* Удобная прокрутка с учётом фиксированного хедера */
.section { scroll-margin-top: 80px; }
Псевдоэлементы ::before и ::after
Чаще всего применяются для декоративных меток, иконок, стрелок и лейблов. Важно: для их отображения почти всегда требуется content (даже пустая строка).
.badge {
position: relative;
display: inline-block;
padding: 6px 10px 6px 26px;
background: #eef4ff;
border-radius: 999px;
}
.badge::before {
content: ""; /* обязателен для ::before/::after */
position: absolute;
left: 8px; top: 50%;
width: 10px; height: 10px;
margin-top: -5px;
background: #2d6cdf;
border-radius: 50%;
}
Другие полезные псевдоэлементы
::first-letter,::first-line— типографика для первых символов/строк.::selection— стиль выделенного текста (поддержка частичная, но полезная).::marker— кастомизация маркеров списков.::placeholder— стиль плейсхолдера инпутов.
ul.custom > li::marker { content: "— "; color: #888; }
input::placeholder { color: #9aa4b2; }
input:focus-visible::placeholder { color: #c4ccd6; }
Современные селекторы: :is(), :where(), :has()
:is(A, B, C)— группировка с нормальной специфичностью по самому «сильному» селектору внутри.:where(A, B)— как:is, но со специфичностью 0 (удобно для сбросов и базовых правил).:has(X)— «родительский» селектор: применяет стиль к элементу, если внутри/рядом есть X. Уже поддерживается современными браузерами.
/* Единый hover для нескольких карточек */
:is(.card, .tile, .product):hover { box-shadow: 0 8px 24px rgba(0,0,0,.12); }
/* Базовая стилизация ссылок в навигации со специфичностью 0 */
.nav :where(a) {
color: #2d2f33;
text-decoration: none;
}
/* Добавить отступ сверху карточкам, где есть изображение */
.card:has(> img) { padding-top: 0; }
/* Подсветить пункт меню со ссылкой на текущую страницу */
.nav li:has(> a[aria-current="page"]) > a { font-weight: 700; }
Паттерны с кодом: быстро и полезно
1) Доступная кнопка с интерактивными состояниями
<button class="btn">Купить</button>
<button class="btn" disabled>Скоро</button>
/* CSS см. выше в примере с .btn */
Не забывайте про :focus-visible — это важно для пользователей клавиатуры и скринридеров.
2) Подсказка (tooltip) без JS на ::after
<button class="tip" data-title="Скидка действует до пятницы">?</button>
.tip {
position: relative;
border: none; background: #2d6cdf; color: #fff;
width: 28px; height: 28px; border-radius: 50%;
}
.tip::after {
content: attr(data-title);
position: absolute;
inset-block-end: 100%; inset-inline-start: 50%;
transform: translate(-50%, -.5rem);
background: #1b1f2a; color: #fff;
padding: 6px 8px; border-radius: 6px;
font-size: 12px; white-space: nowrap;
opacity: 0; pointer-events: none;
transition: opacity .2s ease;
}
.tip:hover::after,
.tip:focus-visible::after { opacity: 1; }
3) Кастомный чекбокс на :checked + ::after
<label class="chk">
<input type="checkbox" class="chk__input">
<span class="chk__box" aria-hidden="true"></span>
Подписаться на новости
</label>
.chk { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.chk__input {
position: absolute; width: 1px; height: 1px;
margin: -1px; padding: 0; border: 0;
clip: rect(0 0 0 0); clip-path: inset(50%);
overflow: hidden; white-space: nowrap;
}
.chk__box {
width: 18px; height: 18px; border: 2px solid #2d6cdf;
border-radius: 4px; position: relative;
}
.chk__box::after {
content: ""; position: absolute; inset: 2px;
background: #2d6cdf; border-radius: 2px;
transform: scale(0); transition: transform .15s ease;
}
.chk__input:checked + .chk__box::after { transform: scale(1); }
.chk__input:focus-visible + .chk__box { outline: 3px solid #ffcc00; outline-offset: 2px; }
4) Подсветка секции по якорю через :target
<nav>
<a href="#faq1">Оплата</a>
<a href="#faq2">Доставка</a>
</nav>
<article id="faq1" class="section">...</article>
<article id="faq2" class="section">...</article>
/* CSS см. блок с :target выше */
Типичные ошибки и как их избежать
- Забыли content у ::before/::after. Без него псевдоэлемент не появится (кроме ряда специфических случаев).
- Нет позиции у контейнера. Для позиционирования псевдоэлементов чаще всего нужен
position: relativeу родителя иabsoluteу ::before/::after. - Только :hover без :focus-visible. На тач-устройствах и при клавиатурной навигации :hover не сработает — добавляйте фокус.
- Слишком высокая специфичность. Используйте
:where()для базовых правил и разумно группируйте селекторы с:is(). - Декор через ::before поверх текста. Проверьте порядок наложения (
z-index) и не перекрывайте интерактивные области.
Поддержка и прогрессивное улучшение
:is и :where поддерживаются повсеместно. :has — в современных браузерах; для старых можно предусмотреть нейтральный стиль по умолчанию и улучшение для новых. Тестируйте ключевые сценарии в последних версиях Chrome, Firefox и Safari.
Где тренироваться дальше
Если хотите быстро закрыть пробелы в верстке и закрепить навыки практикой, рекомендую пройти Прокачать CSS на практике — курс «Вёрстка сайта с нуля 2.0». Курс поможет уверенно работать с селекторами, сетками, адаптивом и собрать полноценные страницы с нуля.
Итоги
Псевдоклассы и псевдоэлементы в CSS — это фундамент, который экономит разметку и ускоряет разработку. Освоив :hover, :focus-visible, :checked, :target и ::before/::after, а также современные :is, :where, :has, вы сможете уверенно решать типовые задачи интерфейсов без лишнего JS и лишних дивов.
-
Создано 08.04.2026 17:01:02
-
Михаил Русаков

Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.