Упрощение CSS с псевдоклассом :is()

Недавно появился повод воспользоваться новым псевдоклассом CSS :is(), и он превосходен! Хочу рассказать, как с его помощью можно значительно уменьшить сложность селекторов.

Что делает :is()

Например, эти два селектора делают одно и то же…

h1, h2, h3, h4, h5, h6 {
font-weight: bold;
}

:is(h1, h2, h3, h4, h5, h6) {
font-weight: bold;
}

Глядя на это, можно подумать… И зачем он нужен?!

В данном случае это верно, его использование бессмысленно.

Где :is() действительно силён, так это в сложных и повторяющихся наборах вложенных селекторов.

Упрощение вложенности селекторов с :is()

Недавно при работе над сайтом было несколько различных утилитарных классов .bg-* для создания разделов с окрашенными фонами.

Некоторые из них (но не все) обладают более темным фоновым цветом, требующим использования белого цвета текста вместо чёрного. На сайте также присутствуют элементы заголовков, отличающиеся по цвету от стандартного цвета текста.

Оригинальный CSS выглядел так…

.bg-primary-dark,
.bg-secondary,
.bg-secondary-dark,
.bg-primary-dark h1,
.bg-primary-dark h2,
.bg-primary-dark h3,
.bg-primary-dark h4,
.bg-primary-dark h5,
.bg-primary-dark h6,
.bg-secondary h1,
.bg-secondary h2,
.bg-secondary h3,
.bg-secondary h4,
.bg-secondary h5,
.bg-secondary-dark h6,
.bg-secondary-dark h1,
.bg-secondary-dark h2,
.bg-secondary-dark h3,
.bg-secondary-dark h4,
.bg-secondary-dark h5,
.bg-secondary-dark h6,
.bg-primary-dark a:not(.btn),
.bg-secondary a:not(.btn),
.bg-secondary-dark a:not(.btn)
{
color: #ffffff;
}

.bg-primary-dark figcaption,
.bg-secondary figcaption,
.bg-secondary-dark figcaption
{
color: #f7f7f7;
}

.bg-primary-dark a:not(.btn):hover,
.bg-secondary a:not(.btn):hover,
.bg-secondary-dark a:not(.btn):hover
{
color: #d9d9d9;
}

Это… слишком много!

Используя псевдокласс :is(), получилось следующее…

:is(.bg-primary-dark, .bg-secondary, .bg-secondary-dark),
:is(.bg-primary-dark, .bg-secondary, .bg-secondary-dark) :is(h1, h2, h3, h4, h5, h6, a:not(.btn))
{
color: var(--color-white);
}

:is(.bg-primary-dark, .bg-secondary, .bg-secondary-dark) figcaption {
color: var(--color-gray-light)
}

:is(.bg-primary-dark, .bg-secondary, .bg-secondary-dark) a:not(.btn):hover {
color: var(--color-gray-medium-dark);
}

Как видите, это проще в написании и восприятии!

Другой подход

Технически, того же результата можно добиться, используя вложенность CSS.

.bg-primary-dark,
.bg-secondary,
.bg-secondary-dark
{

h1, h2, h3, h4, h5, h6,
a:not(.btn)
{
color: var(--color-white);
}

figcaption {
color: var(--color-gray-light)
}

a:not(.btn):hover {
color: var(--color-gray-medium-dark);
}
}

Я нахожу вложенность более удобной для восприятия, в основном потому, что большую часть своей карьеры писал CSS с использованием Sass.

Но это дело вкуса/предпочтения.

Более весомым аргументом в пользу :is() служит то, что он гораздо лучше совместим с браузерами по сравнению с CSS вложенностью.

Небольшая проблема с :is() и специфичностью

В статье The gotchas of CSS Nesting Killian Valkhof указывает на потенциально проблему специфичности с :is()

… помните, что :is() обладает самой высокой специфичностью из всех используемых в нём селекторов.

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

  1. Возможно, не стоит этого делать.
  2. Можно столкнуться с непредвиденным поведением UI из-за специфичности.

Несмотря на потенциальные проблемы, было интересно попробовать :is() и включить его в свой набор инструментов!

Комментарии


Дополнительные материалы

Предыдущая Статья

Тёмный режим для SVG