
Привет, Хабр!
В CSS огромное количество псевдо-элементов и псевдо-классов. Так много, что я не знаю ни одного фронтендера, который помнит все. Я тоже не исключение из этого правила.
Часто нахожу что-то новое и интересное у зарубежных блогеров, рассказывающих о CSS. Так что неудивительно, что мы с вами упускаем пользу. Это нормально.
Сегодня я пришёл к вам, чтобы это исправить. Мы рассмотрим несколько псевдо-элементов и псевдо-классов, которые, по моему мнению, редко используют. Хотя они принесут немало пользы!
Давайте посмотрим, что я вам подготовил.
Псевдо-класс :focus-within
Я лично не понимаю, почему псевдо-класс :focus-within очень редко используется. Мне кажется, что про него забыли. Срочно исправляю ситуацию.
Данный псевдо-класс помогает нам стилизовать родительский элемент, если пользователь сфокусировался на его дочернем элементе. Это полезно для визуальных задач и улучшения пользовательского опыта.
Я нашёл классный пример, где псевдо-класс :focus-within будет полезен. Для демонстрации я включу псевдо-класс :focus-visible, как будто пользователь сфокусировался на ссылке.

<article class="js-active js-material-list__blogpost material-list__item piwikTrackContent"> <div class="material-list__item-text"> <time class="time-block time-block_top" datetime="2026-08-16 21:55:00">17 минут назад</time> <h2 class="material-list__title"> <a class="h2 material-list__title-link" href="3440113.html">«Спартак» наконец-то победил «Балтику». Угальде разошелся – хорош и в паре с Даку</a> </h2> <p> Пропустили после аута Бевеева. <!-- здесь счётчик лайков --> </p> </div> <a class="material-list__item-img-link material-list__item-img-link_float_right" href="https://www.sports.ru/football/blogs/3440113.html"> <!-- здесь превьюшка --> </a> </article>
Мы видим, что обводка появилась вокруг ссылки. Уже здорово, что она есть. Но визуально она выглядит инородно. Мне кажется, было бы лучше, если она обводила весь блок с новостью.
Для этого нужно объявить псевдо-класс :focus-within для родительского элемента.

.piwikTrackContent:focus-within { outline: 3px solid currentColor; }
Согласитесь же, что так лучше? Мы видим ровную обводку без каких-то зигзагов, которая повторяет контур элемента. Красота!
Псевдо-классы :is() и :where()
Периодически нам приходится группировать стили, которые применяются с помощью разных селекторов. Для этого в CSS есть запятая. В большинстве случаев всё отлично работает. Но если селектор сложный, у нас появляется повторяющаяся часть.
Для демонстрации я применю свойство line-height для элементов ul и ol, находящихся в элементе с классом .awesome-container.
.awesome-container ul, .awesome-container ol { line-height: 1.5; }
Оба селектора содержат селектор по классу .awesome-container. Нам пришлось скопировать эту часть селектора, чтобы браузеры применили стили корректно.
Коллеги, мы можем сократить эту запись! В CSS есть псевдо-классы :is() и :where(). Они группируют селекторы так, что нет дублирования кода.
Перепишем предыдущие стили с помощью псевдо-класса :is().
.awesome-container :is(ul, ol) { line-height: 1.5; }
Но это не всё! Мы также можем группировать псевдо-классы. Например, сделаем это для псевдо-классов :hover и :focus-visible.
.awesome-link:is(:hover, :focus-visible) { background-color: pink; } .awesome-link:focus-visible { outline: 2px solid currentColor; }
Я использую в своих примерах псевдо-класс :is() чаще из-за нюансов расчёта специфичности. Давайте подробнее на этом остановимся.
Псевдо-класс :where() всегда будет рассчитан со специфичностью 0, 0, 0. Для псевдо-класса :is() браузеры вычислят значение по наиболее специфичному селектору, который был передан.
Для тренировки рассмотрим селектор .awesome-block :is(.list, #block, ul).
.awesome-block :is(.list, #block, ul) { background-color: pink; /* специфичность селектора 1, 1, 0 */ }
Как я говорил выше, специфичность псевдо-класса :is() определяется по самому весомому селектору. В нашем примере таким является селектор #block. Следовательно, специфичность равна 1, 0, 0. Далее она прибавляется к специфичности по классу .awesome-block. В результате получаем общую специфичность 1, 1, 0.
Надеюсь, этот нюанс не оттолкнёт вас от использования псевдо-классов :is() и :where(). Как человек, не любящий копирование кода, я безумно рад им. Они помогли мне сделать ещё один шаг к лаконичности, и поэтому я всем их рекомендую.
Псевдо-класс :nth-child()
Конечно же, вы знаете псевдо-класс :nth-child(). Сотни раз вы использовали его. Это бесспорно. Но мне интересно проверить, знаете ли вы некоторые техники, которые можно с ним сделать.
Например, вы слышали, что псевдо-класс :nth-child() можно использовать без привязки к позиции элемента? Если нет, то я как раз подготовил для вас пример.
Мы будем использовать несколько элементов с классом .awesome-block и стилизовать второй среди них.
<body> <div>1</div> <div class="awesome-block">2</div> <div>3</div> <div class="awesome-block">4</div> <div class="awesome-block">5</div> </body>
.awesome-block:nth-child(2) { background-color: pink; }

Сейчас мы видим, что стили применились к первому элементу с классом .awesome-block, у которого второй порядковый номер в группе. Так получилось, потому что мы указали значение 2.
Если же удалить класс .awesome-block у второго элемента, то стили уже не применятся.
<body> <div>1</div> <div>2</div> <div>3</div> <div class="awesome-block">4</div> <div class="awesome-block">5</div> </body>

Как же сделать так, чтобы стили применились ко второму элементу с .awesome-block без привязки к позиции элемента. Например, чтобы он был четвёртым элементом в группе.
Вот для этой задачи есть расширенный синтаксис of S для псевдо-класса :nth-child(). Давайте объявим его, стилизовав второй элемент с классом .awesome-block.
<body> <div>1</div> <div class="awesome-block">2</div> <div>3</div> <div class="awesome-block">4</div> <div class="awesome-block">5</div> </body>
:nth-child(2 of .awesome-block) { background-color: pink; }

Пожалуйста, обратите внимание, что у этого элемента четвёртый порядковый номер. Получается, что браузер нашёл элемент без привязки к его позиции в группе.
Ещё одной полезной возможностью псевдо-класса :nth-child() являются диапазоны. Так можно сделать, если указать их друг за другом. Первый псевдо-класс будет работать со счётчиком на увеличение, а второй — на уменьшение.
Для демонстрации напишем стили так, чтобы они применились с четвёртого по седьмой элементы.
<body> <div class="awesome-block">1</div> <div class="awesome-block">2</div> <div class="awesome-block">3</div> <div class="awesome-block">4</div> <div class="awesome-block">5</div> <div class="awesome-block">6</div> <div class="awesome-block">7</div> </body>
.awesome-block:nth-child(n+4):nth-child(-n+7) { background-color: pink; }

Вот такие техники можно использовать с псевдо-классом :nth-child(). Когда я не знал их, я всё решал через добавление новых классов. А оказывается, всё можно было решить без них.
Псевдо-элемент ::file-selector-button
Возможность загрузить файл является очень популярной функцией приложения. В вебе долгое время есть тип file для элемента input. Его ещё постоянно прячут, заменяя красивыми кнопками.
Коллеги, уже несколько лет браузеры хорошо поддерживают псевдо-элемент ::file-selector-button. Он позволяет стилизовать стандартную кнопку, которая появляется при использовании элемента input с типом file. Мы можем добавить цвет, тень, скругление углов и т. д. Всё то же самое, что при стилизации обычной кнопки. Например, я сделал голубую с иконкой крестика.
<body> <input class="awesome-uploader" type="file"> </body>
.awesome-uploader { font-size: 0; } .awesome-uploader::file-selector-button { padding: 1.5rem; border: 1px solid #2E9AFF; border-radius: 0.5rem; background-color: #2E9AFF; background-image: url(https://www.avito.st/static/ims/design-system-icons\_plus\_square\_common.svg); background-repeat: no-repeat; background-position: center; cursor: pointer; text-indent: -100vw; }

При подготовке к статье я проверил демонстрацию во всех популярных браузерах. У меня всё работало. Но буду честен, что в реальном проекте я такой подход не использовал.
Но если у вас есть личные проекты или вы делаете закрытые системы, то псевдо-элемент ::file-selector-button точно будет полезен.
Псевдо-элемент ::spelling-error
Я постоянно делаю опечатки. Это у меня очень давно. В школе я мог сделать по пятнадцать ошибок в диктанте. Мог сделать три ошибки в одном слове. Проверяя домашнюю работу, мама всё время говорила: «Я с тобой русский язык забуду».
В общем, я постоянно страдаю. По этой причине я не люблю что-то печатать. Хотя разработчики могут немного помочь мне. В CSS есть псевдо-элемент ::spelling-error. Он позволяет стилизовать текст, если в нём есть опечатки.
Давайте посмотрим, как он работает на примере. Я как раз подготовил текст, в котором есть слова с опечатками. Выделим их, добавив свойства background-color и text-decoration.
<body> <label for="msg">Ваше сообщение</label> <textarea id="msg"> Привет! Это сообщенее для тех, кто ошибоется при напечатовании текста. </textarea> </body>
textarea::spelling-error { background-color: rgba(255, 42, 81, 0.2); text-decoration: underline 2px solid rgba(255, 42, 81, 1); text-underline-offset: 4px; }

Конечно, этот способ не решит все проблемы. Но псевдоэлемент ::spelling-error хорош тем, что он позволяет сделать минимальную подсказку.
Это же всего пара строк CSS, которые не занимают много времени у разработчика, и их легко добавить в текущий проект.
Заключение
Давайте подведём итог. В этой статье мы рассмотрели:
псевдо-класс
:focus-withinдля визуального улучшения выделения элементов, содержащих интерактивные элементы;как группировать селекторы без дублирования с помощью псевдо-класса
:where()и:is();псевдо-элемент
::file-selector-button, позволяющий создавать красивые кнопки загрузки файлов с помощью элементаinputс типомfile;как можно заставить работать псевдо-класс
:nth-child()без привязки к порядковому номеру в группе элементов;диапазоны для стилизации элементов с помощью псевдо-класса
:nth-child();выделение слов с опечатками с помощью псевдо-элемента
::spelling-error.
Вот такой список я отобрал для вас. Мне также будет интересно прочитать, какие псевдо-классы и псевдо-элементы вы считаете полезными. Поделитесь, пожалуйста, в комментариях.
На этом всё. Спасибо за чтение!
P. S. Помогаю больше узнать про CSS и дружелюбные интерфейсы в своих ТГ‑каналах CSS isn't magic и UX + Dev = a11y. Присоединяйтесь. Как вступить, написано в профиле.
© 2026 ООО «МТ ФИНАНС»
Комментарии (2)

Metotron0
25.08.2026 09:55псевдо-элемент
::file-selector-button. Он позволяет стилизовать стандартную кнопкуА как вы убрали надпись No file selected, которая потом заменяется именем файла?
k12th
А нестинг не то же самое? И даже более читаемо, кмк. Хотя поддержка у
:isполучше, конечно.