Несколько нюансов использования пользовательских свойств

Несколько нюансов использования пользовательских свойств

От автора: в последнее время я заметил некую проблему при использовании пользовательских свойств, которая сбивает людей с толку, включая и меня, поэтому я постараюсь описать ее.

Добавим в CSS пару пользовательских свойств:

html { --color-1: red; --color-2: blue;
}

Давайте сразу воспользуемся ими, чтобы сделать фоновый градиент:

html { --color-1: red; --color-2: blue; --bg: linear-gradient(to right, var(--color-1), var(--color-2));
}

Теперь предположим, что на странице есть пара div:

<div></div>
<div class="variation"></div>

Позвольте мне стилизовать их:

div { background: var(--bg);
}

Это работает! Теперь позвольте мне добавить несколько изменений. Я не хочу, чтобы цвет менялся с красного на синий, я хочу, чтобы он изменился с зеленого на синий. Проще говоря, я изменю красный цвет на зеленый:

html { --color-1: red; --color-2: blue; --bg: linear-gradient(to right, var(--color-1), var(--color-2));
}
div { background: var(--bg);
}
.variation { --color-1: green;
}

Это не работает, друзья.

Проблема, насколько я понимаю, в том, что –bg никогда не было объявлено ни в одном из div. Его можно использовать, потому что он был объявлен выше, но к тому времени, когда используется –bg, его значение заблокировано. Тот факт, что вы меняете какое-то другое свойство, которое использует –bg во время его объявления, не означает, что свойство прекращает поиск мест, где оно использовалось, и обновляет все, что использовало его в качестве зависимости.

Ух, такое объяснение кажется не совсем правильным. Но это лучшее, что у меня есть. Решение? Ну есть несколько.

Решение 1. Область видимости переменной.

html { --color-1: red; --color-2: blue;
} div { --bg: linear-gradient(to right, var(--color-1), var(--color-2)); background: var(--bg);
}
.variant { --color-1: green;
}

Теперь, когда –bg объявлено в обоих div, изменение зависимости —color-1 действительно работает.

Решение 2. Разделите запятыми селектор, в котором вы устанавливаете большинство переменных.

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

html,
div { --color-1: red; --color-2: blue; --bg: linear-gradient(to right, var(--color-1), var(--color-2));
}
div { background: var(--bg);
}
.variation { --color-1: green;
}

В другом, возможно, менее надуманном примере это могло бы выглядеть примерно так:

:root, .button,
.whatever-it-is-a-bandaid { --padding-inline: 1rem; --padding-block: 1rem; --padding: var(--padding-block) var(--padding-inline);
} .button { padding: var(--padding);
}
.button.less-wide { --padding-inline: 0.5rem;
}

Решение 3. Везде ставь переменные.

* { --access: me; --whereever: you; --want: to; --hogwild: var(--access) var(--whereever);
}

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

Решение 4. Введите новое дефолтное свойство.

Вся заслуга Стивена Шоу, который исследовал проблему, и это одно из первых мест, где я впервые увидел путаницу. Вернемся к нашей первой демонстрации:

html { --color-1: red; --color-2: blue; --bg: linear-gradient(to right, var(--color-1), var(--color-2));
}

Мы хотим получить две вещи:

Способ переопределить весь фон

Способ перекрыть часть градиентного фона

Итак, мы сделаем так:

html { --color-1: red; --color-2: blue;
}
div { --bg-default: linear-gradient(to right, var(--color-1), var(--color-2)); background: var(--bg, var(--bg-default));
}

Обратите внимание, что мы не объявляли —bg вообще . Он просто сидит и ждет значения, и если он когда-нибудь его получит, то «побеждает» именно это значение. Но без него будет использоватся —bg-default. Теперь…

Если я устанавливаю —color-1 или —color-2, то будет заменена часть градиента, как и ожидалось (если я делаю это с помощью селектора, который касается одного из div).

Или я могу настроить сброс фона –bg на все, что захочу.

Похоже на хороший способ.

Иногда возникают настоящие ошибки с пользовательскими свойствами CSS. Ситуации описанные выше — это не одни из них. Хотя нам кажется, что у нас ошибка, по-видимому, это не так. Просто — это одна из тех вещей, о которых Вам нужно знать.

Автор: Chris Coyier

Источник: css-tricks.com

Редакция: Команда webformyself.

Читайте нас в Telegram, VK, Яндекс.Дзен