Я уже достаточно давно экспериментирую с CSS-переменными. Если вы к ним еще не подступались, вы можете воспользоваться этим кратким руководством, чтобы быстро во всем сориентироваться и приступить к работе.
Что это такое?
Простой пример применения для кнопок с областью видимости
CSS-переменные позволяют вам определять многократно используемые значения в CSS.
Они появились уже достаточно давно. Недавно они стали набирать популярность в связи с более широкой поддержкой браузерами.
Если вы пользуетесь препроцессором, например SASS, то с переменными вы уже знакомы. Теперь можно делать все то же самое без препроцессора.
Зачем использовать переменные стиля?
Переменные позволяют нам придерживаться принципа DRY (don't repeat yourself). Благодаря им у нас также появляется способ создать единую точку ссылки для повторяющихся значений. Если вы пользуетесь препроцессором, то, скорее всего, преимущества такого подхода вам уже знакомы. Чаще всего это используют, чтобы задать основной цвет, который используется для множества элементов.
Повтор фонового цвета для нескольких селекторов
Во фрагменте выше значение #e74c3c
могло бы и должно бы быть переменной. Если из этого значения сделать переменную, у нас получится единая точка, на которую можно ссылаться. Это снижает риск появления багов и проблем со стилем, поскольку облегчает дальнейшее обслуживание.
Создание точки ссылки с помощью переменной
Во втором фрагменте я использую препроцессор, чтобы показать, как можно использовать переменную для значения background-color
.
Почему бы не пользоваться переменными препроцессора вместо нативных CSS-переменных?
Хороший вопрос. В большинстве случаев вы предпочтете сохранить приверженность переменным препроцессора. Это так, если вы ими уже пользуетесь. Но можно применять преимущества обоих подходов сразу. Это становится актуально, когда возникает необходимость в полной мере задействовать возможности нативных CSS-переменных. Об этом позже.
Нативные CSS-переменные стоит применять когда:
- У вас нет препроцессора или вы им не пользуетесь.
- Вы хотите использовать преимущества нативных CSS-переменных.
Главные преимущества нативных CSS-переменных
На мой взгляд нативные CSS-переменные имеют два больших преимущества.
Первое. Они обновляются во время выполнения! Ими можно управлять с помощью медиазапросов, состояний или даже JavaScript. Браузер применит внесенные изменения. Это открывает много возможностей.
Кроме того, CSS-переменные позволяют учитывать область видимости. Это означает, что можно поменять, допустим, стиль или поведение элемента путем обновления значения переменной. В противном случае приходится с нуля прописывать новые стили для этого элемента. В результате объем СSS на выходе уменьшается.
Не самый красивый синтаксис
Давайте рассмотрим пример.
Что из себя представляет псевдоселектор :root
? Все логично: это псевдоселектор корня дерева. Селектор :root
можно использовать для определения глобальных переменных. В этом случае мы определяем значение rebeccapurple
для переменной --primary
.
Чтобы определить переменную, в качестве префикса используется два дефиса.
Чтобы использовать переменную нам потребуется функция var
.
А что происходит, когда мы ссылаемся на переменную, значение которой не задано? В этом случае можно задать резервные значения или значения по умолчанию. Функция var
поддерживает второй необязательный параметр, соответствующий резервным значениям или значениям по умолчанию.
В этом фрагменте задается исходный стиль для тега button
. Где возможно для background-color
применяется значение --btn-color
. Если переменная не существует или значение не задано, используется значение --primary
.
Нет необходимости использовать переменную для нашего фолбека. Можно взять значение. Но с переменными будет проще осуществлять поддержку кода.
Обратите внимание, что для button.btn
никаких стилей не объявлено. Вместо этого обновляется значение. Теперь уместно перейти к каскадированию и областям видимости.
Каскадирование и области видимости
При работе с переменными учитывается каскадирование, а также область видимости переменных. Во предыдущем примере переменные объявляются в псевдоклассе :root
. Все переменные в селекторе :root
имеют глобальную область видимости.
В одном из примеров выше --primary
был доступен для всех селекторов. Благодаря области видимости это значение можно переопределить. Например, нам нужно, чтобы значение --primary
менялось для класса premium
.
В этом фрагменте значение переменной --primary
элемента класса premium
равно dodgerblue
. То есть, если для button
не применяется никакой класс, значение переменной — rebeccapurple
. Однако, если применить класс premium
, цвет поменяется на dodgerblue
.
Стоит отметить, что, как и в случае со встроенными стилями, встроенные CSS-переменные имеют наивысший приоритет.
В этом фрагменте фоновый цвет кнопки будет иметь значение red
, несмотря на то, что здесь применяется класс premium
. Это происходит, потому что значение --primary
описано непосредственно в теге.
Управление значениями
Управлять значениями CSS-переменных можно с помощью других CSS-правил. Основные подходы — медиазапросы и изменения состояния.
Например, значение переменной может меняться, когда ширина экрана превышает некую величину.
Изменение запустит перерисовку браузера и покажет результат пользователю.
В этом случае градиент фона поменяется, если ширина превысит 768px
.
А как управлять переменными с помощью состояний? Например, возьмем button
. CSS-переменная будет обновляться исходя из состояния button
.
В этом случае можно настраивать стиль кнопки исходя из состояния :active
.
Управление значениями с помощью JavaScript
Управлять переменными из СSS очень удобно. Но чтобы по-настоящему получить контроль над ними, придется управлять ими посредством JavaScript. К счастью, это реально.
Метод setProperty
позволяет задавать переменные стиля элемента и управлять ими.
Как обновить переменную, заданную в псевдоклассе :root
? Хороший вопрос. Потребуется задать свойства документов documentElement
.
Когда можно управлять CSS-переменными таким образом, открывается много возможностей. Любопытно отслеживать положение курсора с помощью события mousemove
.
Использование calc() и отказ от единиц измерения
Постарайтесь не использовать единиц измерения в переменных. Это облегчит дальнейшее обслуживание.
Функция calc()
позволяет нормализовать и задавать значения с желаемыми единицами измерения.
CSS-переменные можно даже использовать для хранения информации о предпочитаемых единицах измерения. Во фрагменте для наглядности мы взяли «1px», но можно заменить это на «1pt», «1rem» и т.д.
Отсутствие единиц измерения, как правило, более актуально, когда значения задаются из JavaScript. При обработке чистых значений наш скрипт абстрагируется от CSS. Нарушается связь.
Когда единицы измерения содержатся в CSS, обслуживание тоже проходит через CSS.
Примеры применения
Я все еще изучаю различные примеры применения CSS-переменных. В первую очередь в голову приходит динамическая темизация. Отслеживание курсора и прокрутки экрана — тоже любопытные применения. Я подготовил обучающие материалы, которые можно найти ниже.
Пример с собакой и мячиком
Давайте один пример проработаем вместе!
Здесь мы просто отслеживаем положение курсора и обновляем положение двух эмодзи.
Главное здесь — перенести эмодзи из центральной точки с помощью translate
и одновременно применить transition-delay
для собаки.
Как обновить положение? С помощью переменных для --x
и --y
.
Как сделать так, чтобы собака отставала? Применяется transition-delay
. Непростого эффекта замедления можно также добиться с помощью transition-timing-function
.
Остается лишь обновить эти переменные для mousemove
.
Вот и все. Еще пара небольших доработок, и получается что-то в этом роде:
Недостатки
Пока что работа с CSS-переменными шла достаточно гладко. Мне редко встречались ситуации, когда что-то не получалось. Приведу несколько возможностей, которые хотелось бы увидеть для CSS-переменных.
- Анимация переменных. В этой статье я совсем не говорил про анимацию. Для нее можно использовать переменные. Но анимацию самих значений сделать не получится.
- В селекторах CSS-переменные использовать нельзя. Это логично, но было бы здорово, если такой уровень интерполяции был бы доступен. Использовать переменные в селекторе nth-child было бы круто.
Заключение
Работать с CSS-переменными мне нравится. Чем больше я ими занимаюсь, тем больше примеров применения приходят в голову.
Благодаря этой статье вы сами можете начать изучать CSS-переменные.
Если вам интересно получить более подробный обзор CSS-переменных, посмотрите это видео.
LOOKING.HOUSE — на проекте собрано более 150 точек looking glass в 40 странах. Можно быстро выполнить команды host, ping, traceroute и mtr.