На протяжении многих лет одной из самых частых просьб к рабочей группе CSS была реализация хоть какой-то поддержки объявления и использования переменных в таблицах стилей. После долгих обсуждений, в спецификации CSS Custom Properties for Cascading Variables был принят подход, позволяющий автору устанавливать пользовательские свойства в стилевых правилах, которые каскадируются и наследуются, как и другие наследуемые свойства. Обращения к переменным могут быть выполнены в определениях значений свойства, с использованием синтаксиса var()
.
Пользовательские свойства, объявляющие переменные, должны именоваться начиная с var-
. Значения этих пользовательских свойств практически произвольны. Они могут принимать почти любую вереницу символов, при условии что она сбалансирована.
Например, автор может объявить какие-то общие значения в стилевых правилах для корневого элемента, таким образом они будут доступны для каждого элемента документа:
:root {
var-theme-colour-1: #009EE0;
var-theme-colour-2: #FFED00;
var-theme-colour-3: #E2007A;
var-spacing: 24px;
}
Обращаться к переменным можно в любом месте внутри значения другого свойства, включая остальные пользовательские свойства. Переменные из вышеуказанной таблицы стилей могут быть использованы, например, следующим образом:
h1, h2 {
color: var(theme-colour-1);
}
h1, h2, p {
margin-top: var(spacing);
}
em {
background-color: var(theme-colour-2);
}
blockquote {
margin: var(spacing) calc(var(spacing) * 2);
padding: calc(var(spacing) / 2) 0;
border-top: 2px solid var(theme-colour-3);
border-bottom: 1px dotted var(theme-colour-3);
font-style: italic;
}
Если их применить к этому документу:
<!DOCTYPE html>
<h1>The title of the document</h1>
<h2>A witty subtitle</h2>
<p><em>Please</em> consider the following quote:</p>
<blockquote>Text of the quote goes here.</blockquote>
результат будет выглядеть как-то так:
Переменные вычисляются на основании значения переменной того элемента к которому применяется свойство со ссылкой на переменную. Если элемент h2
содержит атрибут style="var-theme-colour-1: black"
, тогда правило h2 { color: var(theme-colour-1); }
будет вычислено с использованием этого значения, а не того, что определено в правиле :root
Ссылки на переменные так же могут включать в себя запасные значения, которые используются в случае, если переменная не определена или недействительна (из-за участия в цикле обращений к переменной). Первое правило в таблице стилей с использованием переменных можно переписать в виде:
h1, h2 {
color: var(theme-colour-1, rgb(14, 14, 14));
}
что в результате приведет к установке темно-серого цвета, если переменная theme-colour-1
не определена в одном из заголовочных элементов.
Поскольку ссылки на переменные раскрываются используя значение переменной в конкретном элементе, этот процесс должен быть выполнен во время определения вычисленного значения свойства. Всякий раз, когда возникает ошибка в процессе подстановки переменной, свойство становиться «недопустимым во время вычисления значения» (“invalid at computed-value time”). Ошибки могут возникать из-за обращения к не объявленной переменной, не имеющей запасного значения, или потому, что подставляемое в свойство значение не было распарсено (например, если мы указали для переменной theme-colour-1
не цветовое значение и затем применили его для свойства color
). Если свойство недопустимо во время вычисления значения, само объявление этого свойства парсится успешно, и его можно увидеть, если изучить объект CSSStyleDeclaration в дереве DOM. Однако вычисленное значение этого свойства примет значение по умолчанию. Для наследуемых свойств, таких как color
, значением по умолчанию будет inherit
. Для не наследуемых свойств, initial
.
Реализация
Начальная реализация CSS переменных только что добавлена в Firefox Nightly, актуальной является 29 версия. Этот функционал пока не доступен в релизных сборках (таких как, Firefox Beta и релизная версия Firefox), так как прежде чем сделать его широкодоступным, мы ждем решения некоторых проблем в спецификации и для этого шагаем чуть дальше на ниве W3C Process. Однако все это и дальше будет доступно в Nightly, а после 3 февраля перейдет и в Firefox Aurora.
Единственная не реализованная на данный момент часть спецификации — это CSSVariableMap
, представляющая объект, который напоминает ECMAScript Map
с методами get
, set
и другими методами для получения значений переменных на основании CSSStyleDeclaration
. Однако, помните, что вы все еще можете добраться до них в DOM-дереве, используя методы getPropertyValue
и setProperty
, при условии, что вы используете полные названия свойств, как например var-theme-colour-1
.
Работа над этой функцией была выполнена в рамках решения бага 773296, и я благодарю Дэвида Барона за обзоры и Эммануэллу Басси, которая выполнила кое-какие стартовые работы по реализации. Если вы столкнетесь с какими-либо проблемами, используя эту функцию, пожалуйста, сообщите об ошибке!
Оригинал: CSS Variables in Firefox 29
Автор: andreyalt