Кастомные свойства в CSS. Часть 3: ограничения

Kate

Administrator
Команда форума
Эта статья будет полезна, если вы уже знакомы с основами кастомных свойств в CSS: синтаксисом, особенностями контекста при использовании кастомных свойств и реактивностью при управлении через JavaScript. Понимаете, как применять контекст и фоллбэки для кроссбраузерности. Знаете, какая разница между кастомными свойствами и препроцессорными переменными. Если что-то из этого вам не знакомо, прочтите статью про основы кастомных CSS-свойств и про их особенности. Это достаточно исчерпывающее руководство, чтобы начать применять технологию в проектах. Но не хватает одной детали: используя любую технологию, нужно знать ограничения, которые она накладывает на разработку. Разберём, что кастомные свойства не умеют делать.

Кастомные свойства — это текст​

Начнём с незамысловатых сложностей. Кастомные свойства — это текст. И любой текст с указанием кастомного свойства валиден внутри CSS-правил:

.block {
background-color: #1e1e1e;
background-color: Мой любимый цвет — var(--my-color);
}
Третью строку браузер посчитает валидной, при этом вторая не сработает:



Правильный код перезапишется на неправильный. Это кажется странным и нелогичным. Нужно помнить об этой особенности кастомного свойства, чтобы не допускать таких ошибок.

Анимируются только в виде значений​

Кастомные свойства анимировать не получится, можно анимировать только другие свойства, которые ссылаются на значения, заданные в кастомных свойствах. Это лежит на поверхности, но соблазн написать подобное при разработке велик:

/* Заведомо неправильный пример */

button {
--scale: scale(1);
transition: --scale .3s linear;
transform: var(--scale);
}

button:hover {
--scale: scale(1.2);
}
Этот пример кода — демонстрация хода мышления, который заведёт в тупик. Кастомное свойство подставляет значение, которое хранится в нём в виде текста.

Такой пример сработает:

button {
--property: transform;
--scale: scale(1);
--duration: .3s;
--timing-func: linear;
transition: var(--property) var(--duration) var(--timing-func);
transform: var(--scale);
}

button:hover {
--scale: scale(1.2);
}

Не работают в медиазапросах​

Несмотря на то, что кастомные свойства — текст, они не работают при объявлении медиазапросов. Это странно для тех, кто привык к переменным в препроцессорах.

Так сделать не получится:

:root {
--tablet-width: 720px;
}

body {
background-color: #1e1e1e;
}

@media screen and (max-width: var(--tablet-width)) {
body {
background-color: #000;
}
}
Хотя аналогичный с виду код на SCSS скомпилируется в CSS и будет работать:

$tablet-width: 720px;

body {
background-color: #1e1e1e;
}

@media screen and (max-width: $tablet-width) {
body {
background-color: #000;
}
}
Это неприятное ограничение. Тем не менее в теле медиазапросов кастомные свойства работают: основываясь на них, вы можете переопределять значения внутри селекторов.
https://tproger.ru/jobs/frontend-razrabotchik-middle/?utm_source=in_text
Так можно:

:root {
--body-color: #1e1e1e;
}

body {
background-color: var(--body-color);
}

@media screen and (max-width: 720px) {
body {
--body-color: #000;
}
}

Проблемы фоллбэков и недостатки постпроцессинга​

В статье про особенности кастомных свойств приведён пример кода, который не подойдёт для продакшена. Разберёмся, что с ним не так. Для этого вспомним, что делает POSTCSS, когда адаптирует код с кастомными свойствами под Internet Explorer.

Если кастомные свойства заданы на уровне корневого элемента, POSTCSS сделает фоллбэк:

:root {
--some-perfect-color: #1e1e1e;
}

body {
background-color: #1e1e1e; /* этот фоллбэк сделал POSTCSS */
background-color: var(--some-perfect-color);
}
То же самое будет, если задать кастомное свойство на уровне блока, но указать альтернативное значение:

.block {
--some-perfect-color: #1e1e1e;
background-color: #1e1e1e; /* этот фоллбэк сделал POSTCSS */
background-color: var(--some-perfect-color, #1e1e1e);
}
А так выглядит код, который не применим в реальных проектах, где нужна поддержка IE:



Если мы запустим постпроцессинг на файле style.css плагином postcss-custom-properties , получим такой код.

В нём есть проблемы:

1. Фоллбэки — тоже кастомные свойства. Всё, что идёт после запятой в обращении к кастомному свойству, POSTCSS считает альтернативным значением. Но IE не поймёт этого фоллбэка.

.page__title {
font-size: 36px;
text-transform: uppercase;
font-weight: 700;
color: var(--color-blue);
color: var(--title-color, var(--color-blue));
}
Можно немного «потанцевать с бубном» и добиться нужного фоллбэка, если написать в исходном файле что-то такое:

.page__title {
font-size: 36px;
text-transform: uppercase;
font-weight: 700;
color: var(--title-color, var(--color-blue, #005cff));
}
Тогда после двух последовательных запусков постпроцессинга мы получим полотно дублирующегося кода, но с фоллбэком. Да, повторяющийся код можно удалить плагинами, но это неудобно ни в настройке, ни при написании исходного CSS.

2. Переопределённым кастомным свойствам невозможно прописать фоллбэки.

Посмотрим код из результата постпроцессинга:

.page__section_type_canceled {
--title-color: var(--color-red);
--border-color: var(--color-red);
}
Он идентичен исходному коду — ничего не произошло. POSTCSS-плагин никак не разгадает нашу задумку с наследованием кастомного свойства от модификатора. Чтобы всё заработало, POSTCSS должен просмотреть всех наследников блока с модификаторами в DOM и написать ещё два CSS-блока для вложенных элементов. Это за гранью его возможностей.

В общем, если вы хотите использовать кастомные свойства, применяя принципы каскада, про Internet Explorer стоит забыть.

Итоги​

Работа над кастомными свойствами в CSS продолжается и скоро мы увидим новые фишки. Уже сейчас Google Chrome в 85-й версии экспериментирует со свойством property, разработанным проектом Houdini. Это направление кажется многообещающим: в кастомных свойствах появятся типы и исходные значения. Если хотите овладеть кастомными CSS-свойствами ещё больше, ознакомьтесь с документацией. И практикуйтесь. Много практикуйтесь.

Источник статьи: https://tproger.ru/articles/custom-properties-in-css-part-3/
 
Сверху