Псевдоклассы :is() и :where() для чистого кода

Забудь про селекторы-простыни: Укрощаем CSS с помощью :is() и :where()

Слушай, вспомни тот момент, когда ты открываешь чужой (или свой полугодовалый) проект и видишь там селектор длиной в три строки. Что-то вроде header h1, header h2, footer h1, footer h2, section h1... и так далее. Это выглядит как список покупок, в котором легко запутаться, а поддерживать такую «красоту» — то еще удовольствие. Раньше мы просто мирились с этим или прятали проблему за вложенностью в Sass, но браузеры-то все равно получали на вход этот огромный неповоротливый ком кода.

Сегодня я покажу тебе, как выкинуть этот мусор и писать селекторы, которые выглядят чисто, работают эффективно и не заставляют твои глаза кровоточить. Погнали разбираться с :is() и :where().

Как мы страдали раньше

До появления этих псевдоклассов у нас было два пути, и оба вели в тупик. Либо ты вручную перечислял все комбинации через запятую, либо использовал препроцессоры. Но у препроцессоров была ловушка: когда ты пишешь красивую вложенность в SCSS, на выходе получается монструозный CSS-файл, который весит больше, чем должен.

Еще одна боль — специфичность. Если в твоем длинном списке один селектор оказывался невалидным (например, опечатка в нестандартном псевдоэлементе), весь блок стилей просто отваливался. К тому же, управление приоритетами превращалось в войну !important. Чтобы по-настоящему взять специфичность под контроль, советую глянуть статью про Cascade Layers (@layer) в CSS — это идеальное дополнение к тому, о чем мы говорим сегодня.

Как делать правильно в 2026 году

Современный подход — это использование :is() для группировки и :where() для обнуления специфичности.

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

Кстати, если ты любишь чистоту не только в селекторах, но и в типографике, зацени материал про text-wrap: balance и pretty, это сделает твои заголовки еще сексуальнее.

Готовый сниппет кода

Давай сравним старый подход и новый. Посмотри, насколько чище становится структура:


/* Раньше: Громоздко и сложно поддерживать */
header .title, 
header .subtitle, 
section .title, 
section .subtitle, 
footer .title, 
footer .subtitle {
  color: var(--primary-color);
  font-family: sans-serif;
}

/* Сейчас с :is(): Элегантно и читаемо */
:is(header, section, footer) :is(.title, .subtitle) {
  color: var(--primary-color);
  font-family: sans-serif;
}

/* С :where(): Стили с нулевой специфичностью для легкого переопределения */
:where(article, aside) p {
  line-height: 1.6;
  margin-bottom: 1rem;
}

Частая ошибка новичков

Самый частый затык — непонимание разницы в специфичности. Новички часто используют :is() там, где нужно было использовать :where(), и наоборот.

Запомни: если ты пишешь стили для UI-кита или базовые стили темы, которые должны легко перебиваться любым кастомным классом — используй :where(). Если же ты просто хочешь сократить запись в логике основного приложения — бери :is(). И никогда не забывай: :is(.class, #id) получит специфичность ID, даже если ты применяешь его к элементу с классом. В этом коварство :is() — он всегда равняется на самого мощного парня в своей компании.

🔥 Больше фишек, готовых сниппетов и передовых подходов к CSS мы публикуем в нашем Telegram-канале. Подписывайтесь, чтобы не пропустить!

🚀 Прокачай свой код

Готовые CSS-сниппеты, разбор продвинутых фишек и эксклюзивные материалы — в нашем Telegram-канале.

Подписаться
error: Content is protected !!
Прокрутить вверх