Selectors Level 4 – четвёртый уровень модуля селекторов CSS, развивающий Selectors Level 3. Важная оговорка: это не «CSS4». После CSS3 спецификация стала модульной – единой версии у CSS больше нет, каждый модуль (селекторы, гриды, вложенность) растёт своим уровнем. Именно Level 4 принёс в веб :is(), :where(), :has() и списки внутри :not(), а заодно закрепил современные правила подсчёта специфичности селекторов.
Как это работает
Статус документа – W3C Working Draft, действующая редакция от 22 января 2026 года. Это рабочий черновик, а не рекомендация (Recommendation): W3C помечает, что документ может обновляться и заменяться, а часть возможностей отмечена как at-risk – их могут исключить при переходе на следующую стадию. Отсюда два практических вывода. Первый: русскоязычные обзоры «селекторов CSS4» в выдаче датируются 2015 годом и описывают ранний драфт – в них ещё фигурирует псевдокласс :matches(), который решением CSSWG (issue #3258) переименован в :is(). Второй: «черновик» не значит «нельзя использовать» – браузеры реализуют возможности по мере готовности, и ядро Level 4 давно работает в продакшене.
Level 3 и Level 4 – в чём разница
| Возможность | Что делает | Поддержка |
|---|---|---|
:is() | Список селекторов одним псевдоклассом (бывший :matches()) | Baseline Widely available, все браузеры с января 2021 |
:where() | То же, но с нулевой специфичностью | Baseline Widely available, с января 2021 |
:has() | Реляционный «селектор родителя» | Baseline Widely available с декабря 2023 |
:not(a, .b) | Список вместо цепочки :not(a):not(.b) | Широко поддержан |
:nth-child(An+B of S) | Нумерация только среди элементов, подходящих под S | Поддержка неравномерна – сверять с MDN и caniuse |
[attr=v i] | Флаг регистронезависимого сравнения атрибута (есть и s) | Широко поддержан |
:focus-visible, :focus-within | Фокус-кольцо «когда уместно» и фокус внутри контейнера | Широко поддержаны |
||, :nth-col(), :blank, :current, :local-link | Колоночный комбинатор и редкие псевдоклассы | Не поддержаны браузерами |
Кроме перечисленного, Level 4 описывает :any-link (единый псевдокласс гиперссылки), :dir() (направление текста), :scope, а также зеркальный :nth-last-child(An+B of S) с отсчётом с конца. Из той же спецификации – «прощающий» список селекторов (forgiving selector list): невалидный аргумент внутри :is() и :where() просто игнорируется, остальные продолжают работать, тогда как в обычном списке через запятую один невалидный селектор ломает всё правило целиком.
Правила специфичности Level 4: :is(), :not() и :has() получают вес самого специфичного аргумента, :where() – всегда ноль, универсальный селектор и комбинаторы игнорируются. У :has() есть жёсткие ограничения: его нельзя вкладывать в другой :has(), а псевдоэлементы невалидны и внутри аргумента, и в качестве якоря.
Зачем это нужно
Для разработчика Level 4 – это меньше JavaScript и меньше служебных классов в разметке:
- Реакция на содержимое –
:has()закрывает задачи, которые раньше решались скриптами: подсветить пункт меню с активной ссылкой, стилизовать карточку с картинкой или форму с невалидным полем. - Короче код –
:is()сжимает комбинаторные списки в одно правило, а:not()со списком заменяет цепочки отрицаний. - Управляемая специфичность –
:where()с нулевым весом стал стандартом резетов и CSS-библиотек: их стили перебиваются одним классом. - Точная выборка – :nth-child(An+B of S) нумерует только элементы, подходящие под фильтр S, чего классический :nth-child из Level 3 не умел.
- Доступность –
:focus-visibleпоказывает фокус-кольцо клавиатурным пользователям, не раздражая тех, кто кликает мышью.
Смежный модуль CSS Nesting – вложенность с селектором & – построен на механике :is(): «вложенные селекторы как в препроцессорах», которые старые статьи приписывали «CSS4», пришли в браузеры именно этим путём.
Пример
/* :not() со списком (L4) вместо цепочки (L3) */
p:not(.disabled, .hidden) { display: block; }
/* :is() сжимает комбинаторные списки */
:is(section, article, aside) h1 { font-size: 25px; }
/* :where() – то же, но нулевая специфичность */
:where(ol, ul) :where(ol, ul) { margin: 0; }
/* :has() – «селектор родителя» */
li:has(> a.current) { font-weight: bold; }
h1:has(+ h2) { margin-bottom: 0; }
/* :nth-child с фильтром of S */
li:nth-child(even of .noted) { background: tomato; }
/* Регистронезависимый атрибут */
a[href$=".PDF" i] { color: red; }
/* Фокус только с клавиатуры */
button:focus-visible { outline: 2px solid; }Практическое правило внедрения: :is(), :where(), :not() со списком и :focus-visible можно использовать без оговорок, :has() – Baseline Widely available с декабря 2023, для :nth-child(... of S) поддержку стоит сверить по MDN и caniuse, а || и :nth-col() в продакшен-код не брать – они не реализованы браузерами. Держите в уме и «прощающий» список: правило с :is() не сломается целиком из-за одного неподдержанного селектора внутри – это делает Level 4 удобным для постепенного внедрения.