Переменные CSS: --custom-свойства и функция var()

CSS-переменная (custom property) хранит значение под именем, которое начинается с двух дефисов - например, --main-color. Один раз объявив её, можно подставить в любое количество правил через var(--main-color), и при изменении значения переменной обновятся сразу ВСЕ места, где она использована - без поиска и замены по всему файлу.

Попробуй прямо сейчас: нажимай на кнопки цвета. Заголовок, рамка карточки и фон кнопки - три разных свойства у трёх разных элементов - каждый раз перекрашиваются ОДНОВРЕМЕННО, потому что все они ссылаются на одну и ту же переменную --main-color. Поменялась только она - обновилось всё сразу.

Синтаксис: --имя и функция var()

Объявление переменной выглядит как обычное CSS-свойство, но имя обязательно начинается с двух дефисов: --main-color: #2f5fa8;. Без двух дефисов браузер решит, что это просто неизвестное свойство, и молча его проигнорирует. Чаще всего переменные объявляют внутри псевдокласса :root - он соответствует тегу html и делает переменную доступной абсолютно везде на странице, ведь цвет, который раньше приходилось прописывать HEX-кодом в каждом правиле отдельно, теперь достаточно задать один раз. Использовать переменную можно только через функцию var(): color: var(--main-color);.

:root { --gap: 16px; } .card { padding: var(--gap); margin: var(--gap); } - одно число используется сразу в двух местах.

:root { main-color: blue; } .title { color: main-color; } - без двух дефисов и без var() это не переменная, а невалидный CSS, который браузер просто пропустит.

Наследование и каскад: почему это не Sass-переменные

CSS-переменные легко перепутать с переменными из препроцессоров вроде Sass или Less, но разница принципиальная. Sass-переменная - это просто текстовая подстановка, которая происходит один раз при СБОРКЕ проекта: браузер её вообще не видит, получая уже готовое статичное значение. CSS-переменная, наоборот, живёт прямо в браузере и вычисляется в реальном времени - а значит, участвует в обычном каскаде и наследовании. Если переопределить переменную внутри вложенного селектора, новое значение будет действовать только там и внутри, не трогая остальную страницу - обычное поведение каскада, ничего специального.

:root { --accent: blue; } .dark-section { --accent: white; } - внутри .dark-section переменная станет белой, снаружи так и останется синей.

ожидание, что переменная, объявленная внутри .card, будет доступна СНАРУЖИ этого блока - переменные наследуются только ВНИЗ по дереву элементов, не вверх и не в стороны.

var() с запасным значением

У функции var() есть необязательный второй аргумент - запасное значение, которое применяется, если указанной переменной не существует вообще: var(--main-color, black). Это удобно, когда правило может использоваться в разных местах сайта, и не везде гарантированно объявлена нужная переменная - вместо того чтобы стиль просто "сломался", применится разумное значение по умолчанию.

color: var(--accent, #333); - если --accent нигде не объявлена, применится #333, а не пустое значение.

color: var(--accent); без запасного значения - если переменная не определена, свойство color попросту не применится (в спецификации это называется "invalid at computed-value time").

Из истории Первой поддержку CSS custom properties получила Firefox 31 в 2014 году, а до по-настоящему полной кросс-браузерной поддержки пришлось ждать Edge 16 в 2017 году (Chrome и Safari подтянулись годом раньше, в 2016-м). Internet Explorer так и не получил эту возможность никогда - именно поэтому Sass и Less ещё много лет после появления "родных" CSS-переменных оставались обязательными на любом проекте, где нужно было поддерживать старые корпоративные браузеры.

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

ОшибкаЧто происходитКак исправить
Забывают два дефиса в начале имени переменной Браузер не распознаёт запись как переменную и просто игнорирует правило Имя переменной всегда начинается с двух дефисов: --main-color
Ждут, что CSS-переменные ведут себя как Sass-переменные Не понимают, почему значение меняется в разных местах страницы по-разному Помнить, что CSS-переменные - часть каскада и наследования, а не текстовая подстановка при сборке
Объявляют переменную в узком селекторе, а используют её снаружи Переменная "не находится" - применяется значение по умолчанию или ничего не применяется Общие переменные объявлять в :root, а не в случайном классе
Не указывают запасное значение в var(), когда переменная может отсутствовать Свойство просто не применяется, если переменной не оказалось Указывать var(--имя, запасное-значение) там, где переменная не гарантирована

Шпаргалка

Что нужноКак сделать
Объявить переменную--имя: значение; (два дефиса обязательны)
Использовать переменнуюvar(--имя)
Запасное значениеvar(--имя, запасное-значение)
Сделать переменную глобальнойОбъявить внутри :root { ... }
Переопределить локальноУказать то же имя переменной внутри вложенного селектора
Отличие от Sass/LessCSS-переменные живут в браузере, участвуют в каскаде, меняются на лету

Коротко: отвечаем на вопросы

Чем CSS-переменные отличаются от переменных Sass или Less?

Sass и Less - препроцессоры: их переменные превращаются в статичные значения один раз при сборке проекта, браузер их вообще не видит. CSS-переменные живут прямо в браузере, вычисляются в реальном времени, участвуют в каскаде и наследовании, и их можно менять на лету через JavaScript, :hover или медиа-запросы.

Обязательно ли объявлять переменные внутри :root?

Нет, переменную можно объявить в любом селекторе - тогда она будет доступна только внутри него и его потомков. :root удобен именно тем, что соответствует тегу html и делает переменную доступной практически везде на странице, поэтому для общих, часто используемых значений его выбирают по умолчанию.

Что будет, если переменная не определена, а запасного значения в var() нет?

Свойство, использующее такую переменную, просто не применится - браузер не станет подставлять вместо него ничего по умолчанию. Чтобы избежать этого, стоит указывать второй аргумент var(): var(--имя, запасное-значение).

Категория
css
Поделиться в социальных сетях

Отправить комментарий

0 Комментарии

Отправить комментарий (0)

#buttons=(Хорошо) #days=(20)

Мы используем файлы cookie для улучшения работы сайта. Подробнее
Хорошо
×