От автора: в последнее время я заметил некую проблему при использовании пользовательских свойств, которая сбивает людей с толку, включая и меня, поэтому я постараюсь описать ее.
Добавим в CSS пару пользовательских свойств:
1 2 3 4 |
html { --color-1: red; --color-2: blue; } |
Давайте сразу воспользуемся ими, чтобы сделать фоновый градиент:
1 2 3 4 5 6 |
html { --color-1: red; --color-2: blue; --bg: linear-gradient(to right, var(--color-1), var(--color-2)); } |
Теперь предположим, что на странице есть пара div:
1 2 |
<div></div> <div class="variation"></div> |
Позвольте мне стилизовать их:
1 2 3 |
div { background: var(--bg); } |
Это работает! Теперь позвольте мне добавить несколько изменений. Я не хочу, чтобы цвет менялся с красного на синий, я хочу, чтобы он изменился с зеленого на синий. Проще говоря, я изменю красный цвет на зеленый:
1 2 3 4 5 6 7 8 9 10 11 12 |
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. Область видимости переменной.
1 2 3 4 5 6 7 8 9 10 11 12 |
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. Тогда вы столкнетесь с проблемой. Вы можете просто добавить дополнительные селекторы к основному, чтобы убедиться, что вы попали в нужную область.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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; } |
В другом, возможно, менее надуманном примере это могло бы выглядеть примерно так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
: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. Везде ставь переменные.
1 2 3 4 5 6 7 |
* { --access: me; --whereever: you; --want: to; --hogwild: var(--access) var(--whereever); } |
Это плохой подход. Недавно я читал чат, в котором на сайте среднего размера возникла задержка отрисовки страницы в 500 мс, потому что каждое обращение к странице требовало вычисления всех свойств. Пример «работает», но это один из тех редких случаев, когда вы можете вызвать серьезные проблемы с производительностью с помощью селектора.
Решение 4. Введите новое дефолтное свойство.
Вся заслуга Стивена Шоу, который исследовал проблему, и это одно из первых мест, где я впервые увидел путаницу. Вернемся к нашей первой демонстрации:
1 2 3 4 5 6 |
html { --color-1: red; --color-2: blue; --bg: linear-gradient(to right, var(--color-1), var(--color-2)); } |
Мы хотим получить две вещи:
Способ переопределить весь фон
Способ перекрыть часть градиентного фона
Итак, мы сделаем так:
1 2 3 4 5 6 7 8 |
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, Яндекс.Дзен