Нативные переменные в CSS. Уже пора…. Переменные в CSS Как использовать переменные CSS
Функция var() позволяет вставлять значения пользовательских переменных в значения стилевых свойств. var() нельзя использовать в именах селекторов и в свойствах.
Сами пользовательские переменные и их значения описываются внутри произвольного селектора и должны начинаться с двух дефисов. Через двоеточие переменной присваивается любое допустимое для CSS значение.
Aside { --my-font: Helvetica, Arial, sans-serif; }
Для обращения к переменной --my-font используется запись var(--my-font) , которую можно вставлять в качестве значения свойства. При этом область видимости переменной ограничена указанным селектором (aside в данном случае) и применение var(--my-font) в другом селекторе не даст результата. Для создания глобальных переменных их следует описать внутри селектора :root .
Обозначения
Описание | Пример | |
---|---|---|
<тип> | Указывает тип значения. | <размер> |
A && B | Значения должны выводиться в указанном порядке. | <размер> && <цвет> |
A | B | Указывает, что надо выбрать только одно значение из предложенных (A или B). | normal | small-caps |
A || B | Каждое значение может использоваться самостоятельно или совместно с другими в произвольном порядке. | width || count |
Группирует значения. | [ crop || cross ] | |
* | Повторять ноль или больше раз. | [,<время>]* |
+ | Повторять один или больше раз. | <число>+ |
? | Указанный тип, слово или группа не является обязательным. | inset? |
{A, B} | Повторять не менее A, но не более B раз. | <радиус>{1,4} |
# | Повторять один или больше раз через запятую. | <время># |
Значения
<переменная> Имя переменной, обозначается двумя дефисами впереди (--my-font). <значение> Резервное значение, которое подставляется вместо заданного, в том случае, если переменная не определена. Через запятую можно указать несколько значений.
Пример
Кнопки
В данном примере вводятся две переменные: --primary-color и --info-color . Переменная --white не определена, поэтому подставляется указанное значение по умолчанию. Для селектора p.info значение переменной --primary-color переопределяется.
Спецификация
Каждая спецификация проходит несколько стадий одобрения.
- Recommendation (Рекомендация ) - спецификация одобрена W3C и рекомендована как стандарт.
- Candidate Recommendation (Возможная рекомендация ) - группа, отвечающая за стандарт, удовлетворена, как он соответствует своим целям, но требуется помощь сообщества разработчиков по реализации стандарта.
- Proposed Recommendation (Предлагаемая рекомендация ) - на этом этапе документ представлен на рассмотрение Консультативного совета W3C для окончательного утверждения.
- Working Draft (Рабочий проект ) - более зрелая версия черновика после обсуждения и внесения поправок для рассмотрения сообществом.
- Editor"s draft (Редакторский черновик ) - черновая версия стандарта после внесения правок редакторами проекта.
- Draft (Черновик спецификации ) - первая черновая версия стандарта.
CSS-переменные, или, точнее, кастомные CSS-свойства, доступны в Chrome начиная с 49 версии. Они могут быть полезны для уменьшения количества повторяющегося кода в CSS, создания впечатляющих эффектов вроде смены тем на лету и, потенциально, создания полифилов для будущих возможностей CSS.
Хаос в CSS
Обычная практика при разработке приложения - составить набор фирменных цветов, которые будут использоваться, чтобы поддержать единый стиль. Увы, многократное использование этих цветов в CSS не только является рутинной работой, но ещё и создаёт пространство для возникновения ошибок. Если в какой-то момент один из цветов нужно будет поменять, разработчик может неосторожно воспользоваться поиском и заменой по всему документу, что в большом проекте может быть довольно опасно.
В последнее время многие разработчики стали использовать CSS-препроцессоры типа SASS или LESS, которые решают эту проблему с помощью переменных. Хотя эти инструменты заметно увеличили продуктивность разработки, препроцессорные переменные имеют очень серьёзный недостаток: они статичны и не могут меняться на лету. Появление возможности динамически менять переменные не только позволит на лету менять темы сайта или приложения, но также означает значительное расширение возможностей отзывчивого дизайна и возможность создания полифилов для будущих свойств CSS. С выходом Chrome 49 переменные стали доступны в виде кастомных CSS-свойств.
Кастомные свойства в двух словах
Кастомные свойства расширяют наш CSS-инструментарий двумя новыми возможностями:
- Автор кода может присваивать произвольные значения свойствам с придуманными им самим именами.
- Функция var() позволяет затем использовать эти значения в других свойствах.
Краткий пример для демонстрации:
:root { --main-color : #06c ; } #foo h1 { color : var (--main-color); }Функция var() возвращает значение кастомного свойства и заменяется им, в результате чего получается color: #06c; . Если кастомное свойство где-то определено в таблице стилей, оно будет доступно функции var .
На первый взгляд синтаксис может показаться странным. Многие разработчики недоумевают: «Почему бы просто не использовать $foo в качестве имён переменных?» Это было сделано специально для повышения гибкости и возможности в перспективе создавать макросы для $foo . Более подробно об этом можно прочесть в статье одного из авторов спецификации, Таба Аткинса (Tab Atkins).
Синтаксис кастомных свойств
Синтаксис кастомных свойств довольно прост:
Header -color : #06c ;
Обратите внимание, что кастомные свойства регистрозависимы, то есть --header-color и --Header-Color - это два разных свойства. Хотя синтаксис поначалу может показаться незамысловатым, на самом деле он позволяет сделать довольно много. К примеру, ниже - пример валидного кастомного свойства:
--foo: if (x > 5 ) this.width = 10 ;
Хотя это выражение не будет работать в качестве переменной (а также не будет валидным значением любого обычного свойства), потенциально оно может быть прочитано и обработано на лету с помощью JavaScript. Это означает, что кастомные свойства могут открыть доступ ко всевозможным интересным техникам, недоступным с нынешними CSS-препроцессорами. Так что если вы, позёвывая, думаете что-то вроде «Какая разница, у меня есть SASS…», подумайте ещё раз! Это не те переменные, с которыми вы привыкли работать.
Каскад
Кастомные свойства следуют стандартным правилам каскада, так что вы можете определить одно и то же свойство на разных уровнях специфичности:
:root { --color: blue; } div { --color: green; } #alert { --color: red; } * { color: var(--color); } <p > У меня синий цвет, унаследованный от root!p > <div > А для меня установлен зелёный!div > <div id ="alert" > Ну а для меня - красный! <p > И для меня красный: из-за наследования!p > div >
Это означает, что можно использовать кастомные свойства в медиавыражениях для управления отзывчивым дизайном. Примером использования может служить увеличение внешних отступов от основных структурных элементов при увеличении размеров экрана:
:root { --gutter : 4px ; } section { margin : var (--gutter); } @media (min-width: 600px ) { :root { --gutter : 16px ; } }Необходимо отметить, что вышеприведённый приём невозможно повторить используя CSS-препроцессоры, потому что они неспособны переопределять переменные внутри медиавыражений. У этой возможности огромный потенциал!
Также есть возможность использовать кастомные свойства, получающие своё значение из других кастомных свойств. Это может быть крайне полезно для настройки тем:
:root { --primary-color : red; --logo-text : var (--primary-color); }Функция var()
Чтобы получить и использовать значение кастомного свойства, понадобится функция var() . Вот её синтаксис:
var (Здесь
Этот метод особенно пригодится для стилизации веб-компонент, использующих Shadow DOM, поскольку кастомные свойства могут пересекать теневые границы. Автор веб-компоненты может создать начальный дизайн при помощи фолбеков, а потом настроить стили при помощи кастомных свойств:
<x-foo > #shadow <style > p { background-color : var (--text-background, blue); } style > <p > У этого текста жёлтый фон, потому что так указано в документе! Иначе был бы синий. p > x-foo > /* В стилях основного приложения: */ x-foo { --text-background: yellow; }При использовании var() нужно иметь в виду несколько нюансов. Например, переменные не могут быть именами свойств:
.foo { --side : margin-top; var (--side): 20px ; }Это не является эквивалентом присваивания margin-top: 20px; . Более того, второе объявление не является валидным, и выбросит ошибку.
Аналогично, невозможно создать значение, часть которого берётся из переменной:
.foo { --gap : 20 ; margin-top : var (--gap)px ; }Это тоже не является эквивалентом margin-top: 20px; . Чтобы собрать значение, понадобится кое-что другое: функция calc() .
Создание значений с помощью calc()
На случай, если вы никогда раньше с ней не работали, функция calc() - это небольшой, удобный инструмент, позволяющий выполнять вычисления, чтобы определять значения в CSS. Она поддерживается всеми современными браузерами , и её можно использовать вместе с кастомными свойствами для создания новых значений. Например:
.foo { --gap : 20 ; margin-top : calc (var(--gap) * 1px ); /* зашибись */ }Работа с кастомными свойствами в JavaScript
Чтобы получить значение кастомного свойства, используйте метод getPropertyValue() объекта CSSStyleDeclaration.
<p > Этот абзац красного цвета!p > /* JS */ var styles = getComputedStyle(document.documentElement); var value = String(styles.getPropertyValue("--primary-color")).trim(); // value = "red"
Аналогично, чтобы динамически менять значение кастомного свойства, используйте метод setProperty() объекта CSSStyleDeclaration .
/* CSS */ :root { --primary-color: red; } p { color: var(--primary-color); } <p > А теперь этот абзац зелёного цвета!p > /* JS */ document.documentElement.style.setProperty("--primary-color", "green");
Также при задании значения кастомного свойства на лету можно использовать ссылку на другое кастомное свойство, вставив функцию var() в вызов setProperty() .
/* CSS */ :root { --primary-color: red; --secondary-color: blue; } <p > Здорово! Этот абзац синего цвета!p > /* JS */ document.documentElement.style.setProperty("--primary-color", "var(--secondary-color)");
Поскольку кастомные свойства могут ссылаться на другие кастомные свойства, можете представить какие интересные динамические эффекты можно будет делать подобным образом.
Поддержка браузерами
На данный момент кастомные свойства поддерживаются в Chrome 49, Firefox 42, Safari 9.1, и iOS Safari 9.3.
Оригинальная статья: CSS Variables: Why Should You Care? Статью вычитывали:
Всем привет, тема переменных в CSS давно ходит по интернету, однако не все знают о том, что это такое, да и сама технология не так давно вышла в релиз. И хоть использовать её во многих случаях рановато, уже пора понимать что она из себя представляет и как ею пользоваться. Давайте попробуем разобраться с технологией вместе. Обращу ваше внимание, что эта статья для тех, кто не знает о CSS переменных (кастомных свойствах) или только слышал о них. Если вы знакомы и умеете работать с данной фичей, то вам данная статья будет не интересна.
Итак, тема с переменными в стилях уже затерта до дыр, т.к. они давным давно существуют в препроцессорах. Это удобно, я уже плохо представляю себе написание стилей без возможности сохранить где-то определенное значение (цвет, величину, название шрифта, тип маркера у списка, всё что может придти в голову...). Однако препроцессоры не могут дать нам той гибкости, которую дают нативные переменные в CSS, и скоро вы поймете, почему.
Для начала нужно понять, как объявлять и использовать переменные. Переменные объявляются в селекторах:
:root {
--body-background: #ccc;
}
body {
background-color: var(--body-background);
}
Как видно из листинга выше, переменные объявляются двумя дефисами перед именем:
--variable-name
Чтобы использовать переменную, необходимо воспользоваться функцией var . Она имеет 2 параметра. Это, естественно, имя переменной, а вторым необязательным параметром идёт значение свойства, которое необходимо использовать в случае отсутствия переменной.
На этом набор новых возможностей с приходом переменных, разумеется, не заканчивается. Имея переменные в арсенале CSS, мы получаем большую гибкость в написании стилей. Например, теперь чтобы составить медиазапрос для экранов <320px в ширину, не нужно переопределять свойство целиком. Достаточно изменить значение переменной. Т.е.
Title {
--wrapper-width: 50%;
width: var(--wrapper-width);
}
@media (max-width: 320px) {
--wrapper-width: 100%;
}
Всё! Этого достаточно, чтобы свойство width
изменило свое значение!
Если CSS способен отслеживать изменения своих переменных, это значит, что с этим можно взаимодействовать различными способами.
Что насчёт JavaScript?
Управляя аттрибутом style, можно изменить стиль, прибегая к минимальным затратам усилий. Приведу грубый пример на React.Title {
--background: blue;
background-color: var(--background);
}
changeColor() {
this.setState({
style: {"--background": "green"}
});
}
Теперь по клику на элемент с классом title будет меняться цвет фона у элемента. Круто? Ещё бы! Не нужно добавлять новый класс, переопределять свойство или делать другие действия, способствующие изменению фонового цвета у элемента.
Ремарка
Если кто-то не знаком с React или кому-то просто непонятно, что произошло. Мы просто средствами JavaScript изменили аттрибут style у элемента, изменив значение переменной
--background
Используя переменные, изменять css извне стало проще, методов использования можно придумать массу, а мы пойдем дальше.
Области видимости
Нужно сказать пару слов об области видимости CSS переменных, здесь всё просто. Объявленная переменная доступна всем селекторам дочерних элементов данного селектора. Т.е. в листинге ниже использовать переменную --b в тэге html будет нельзя. А вот переменная --a в body и всех дочерних элементах будет работать без проблем (если её конечно не переопределят где-то ниже).Html {
--a: #ccc;
}
body {
--b: #a3a3a3;
}
(я знаю, что цвета в примерах скучные, но я плохо помню цвета по hex-коду:))
Переменные и calc
Как и любое числовое значение свойства, вы можете использовать переменную в функции calc .Title {
--title-width: 300px;
width: calc(var(--title-width) + 150px);
}
Круто! Особенно если учесть что переменную --title-width
, можно менять как внутри CSS, так и извне.
Заметьте, что величину мы обязаны положить в переменную. Дописать px , % , rem и т.д. к вызванной переменной у нас не получится. Однако ничто не мешает нам умножить с помощью функции calc значение на единицу в необходимой нам величине.
Title { --title-width: 300; /* так не сработает */ width: var(--title-width)px; /* так сработает */ width: calc(var(--title-width) * 1px); }