CSS Variables

This version:
http://disruptive-innovations.com/zoo/cssvariables/cssvariables-20080408.html
Latest version:
http://disruptive-innovations.com/zoo/cssvariables/
Revision:
Revision: 1.0
Authors:
Daniel Glazman (Disruptive Innovations)
David Hyatt (Apple, Inc.)

Abstract

Since the release of CSS Level 2 Recommendation ten years ago in may 1998, the Web authors' community has been requesting a way of defining variables in CSS. Variables allow to define stylesheet-wide values identified by a token and usable in all CSS declarations. If a value is often used in a stylesheet - a common example is the value of the color or background-color properties - it's then easy to update the whole stylesheet statically or dynamically modifying just one variable instead of modifying all style rules applying the property/value pair. We expect CSS Variables to receive a very positive feedback from both the Web authors' community and browser vendors.

Status of this document

NOTE: This section describes the status of this document at the time of its publication. Other documents may supersede this document.

Authors welcome suggestions on this document. This document may be updated based on implementation experience, but no commitment is made by the authors regarding future updates. Authors would like the proposals contained in this document to be discussed in the CSS Working Group for open standardization under W3C Process.

Table of contents

  1. Introduction
  2. Requirements
  3. Definition of a variable
    1. The @variables at-rule
    2. Variables and @import
    3. Calling a variable
  4. Grammar
    1. Changes to CSS 2.1 Grammar
    2. Changes to CSS 2.1 Lexical Scanner
  5. Object Model
    1. Changes to interface CSSRule
    2. Interface CSSVariablesRule
    3. Interface CSSVariablesDeclaration
    4. Changes to interface CSSValue
    5. Interface CSSVariable
  6. References

1. Introduction

It is very common to find repeated property values in a CSS stylesheet, for instance to make sure semantically different elements in a web page have a similar rendering and user experience. While CSS offers a mechanism for grouping style rules using groups of selectors, Web designers often tend to neglect it because it decreases the stylesheet's readability and human-based maintainability, and semantically distinct elements rarely share all style rules.

CSS Variables allow authors to define variables that are reusable as property values anywhere in a stylesheet and queryable/modifiable through an extension of the CSS Object Model described in this document.

2. Requirements

RQ1
The definition of a variable and a call to a variable should be simple enough so web authors don't have to drastically change their existing stylesheets to take advantage of CSS Variables. Use case: remove all existing occurrences of a given value in a given stylesheet to replace them by a call to a single variable.
RQ2
The definitions of variables should cross @import boundaries so variables can be contained in a standalone stylesheet and imported by all stylesheets needing them. Use case: company-wide graphical charter for a set of corporate web sites.
RQ3
The value of variable should be modifiable by script. Such a modification should instantaneously update the value of all properties calling the corresponding variable's value, possibly triggering changes in the rendering of the document.
RQ4
Calls to a variable in the assignment of the value of a property should make the corresponding CSS declaration invalid in a non-conformant legacy browser, the CSS error handling rules allowing then a fallback to a regular CSS Level 2 rule.

3. Definition of a variable

3.1. The @variables at-rule

CSS Variables should be defined in an @variables at-rule. An @variable at-rule is composed of the '@' character followed by the 'variables' identifier, optional target media types (separated by commas) and a block of variable definitions. The definition of a variable must precede all style rules contained or imported in the stylesheet.

Each variable definition contained in the block of variables is a declaration composed as CSS style declarations of an identifier, a semi-colon and one value. As in CSS declarations, optional whitespaces and comments are allowed anywhere.

3.2. Variables and @import

The definition of variables crosses @import boundaries. That means that the definition of a variable contained in a stylesheet B imported from a stylesheet A applies to all rules directly contained or imported into stylesheet A.

3.3 Calling a variable

Using the value of a variable as the value or one of the values of a property in a CSS declaration should be achieved using the new functional notation var(). This function takes only one argument being the identifier being the name of the variable. The declaration becomes invalid if the variable does not exist.

Examples:

@variables {
CorporateLogoBGColor: #fe8d12;
}

div.logoContainer {
background-color: var(CorporateLogoBGColor);
}
@variables {
myMargin1: 2em;
}

@variables print {
myMargin1: 2em;
}

.data, div.entry {
margin-left: 30px;
margin-left: var(myMargin1);
}
In the example just above, the left margin of an element carrying the class 'data' will be 2em for instance for the 'screen' medium type, and 10px for the 'print' medium type in a user agent conformant to CSS Variables. A legacy non-conformant browser would apply a 30px left margin to such elements in all media types.

4. Grammar

4.1. Changes to CSS 2.1 Grammar

The following reflects changes to the CSS 2.1 grammar needed for CSS Variables:

  stylesheet
: [ CHARSET_SYM STRING ';' ]?
[S|CDO|CDC]* [ import [S|CDO|CDC]* ]*
+ [ variables [S|CDO|CDC]* ]*
[ [ ruleset | media | page ] [S|CDO|CDC]* ]*
;

+ variables
+ : VARIABLES_SYM S* medium [ COMMA S* medium ]* LBRACE S* variableset* '}' S*
+ ;

+ variableset
+ : LBRACE S* vardeclaration [ ';' S* vardeclaration ]* '}' S*
+ ;

+ vardeclaration
+ : varname ':' S* term
+ ;

+ varname
+ : IDENT S*
+ ;

expr
- : term [ operator term ]*
+ : [ VARCALL | term ] [ operator [ VARCALL | term ] ]*
;

4.2. Changes to CSS 2.1 Lexical Scanner

The following reflects the changes to the CSS 2.1 Lexical Scanner needed for CSS Variables:

  @{I}{M}{P}{O}{R}{T}               {return IMPORT_SYM;}
@{P}{A}{G}{E} {return PAGE_SYM;}
@{M}{E}{D}{I}{A} {return MEDIA_SYM;}
@{C}{H}{A}{R}{S}{E}{T} {return CHARSET_SYM;}
+ @{V}{A}{R}{I}{A}{B}{L}{E}{S} {return VARIABLES_SYM;}
  "url("{w}{string}{w}")"	{return URI;}
"url("{w}{url}{w}")" {return URI;}
+ "var("{w}{ident}{w}")" {return VARCALL;}
{ident}"(" {return FUNCTION;}

5. Object Model

5.1. Changes to interface CSSRule

IDL Definition

interface CSSRule {

// RuleType
const unsigned short UNKNOWN_RULE = 0;
const unsigned short STYLE_RULE = 1;
const unsigned short CHARSET_RULE = 2;
const unsigned short IMPORT_RULE = 3;
const unsigned short MEDIA_RULE = 4;
const unsigned short FONT_FACE_RULE = 5;
const unsigned short PAGE_RULE = 6;
const unsigned short VARIABLES_RULE = 7; // NEW readonly attribute unsigned short type; attribute DOMString cssText; // raises(DOMException) on setting readonly attribute CSSStyleSheet parentStyleSheet; readonly attribute CSSRule parentRule; };
Defined Constants
VARIABLES_RULE: The rule is a CSSVariablesRule.

5.2. Interface CSSVariablesRule

The CSSVariablesRule interface represents a @variables rule within a CSS style sheet. The @variables rule is used to specify variables.

IDL Definition

interface CSSVariablesRule {

readonly attribute stylesheets::MediaList media;
readonly attribute CSSVariablesDeclaration variables;
};

Attributes

media of type stylesheets::MediaList, readonly
A list of media types for this rule. See also the CSS Media Queries specification.
variables of type CSSVariablesDeclaration, readonly
The block of variable declarations of this rule.

5.3. Interface CSSVariablesDeclaration

The CSSVariablesDeclaration interface represents a single block of variable declarations.

IDL Definition

interface CSSVariablesDeclaration {
attribute DOMString cssText;
// raises(DOMException) on setting

DOMString getVariableValue(in DOMString variableName);
DOMString removeVariable(in DOMString variableName)
raises(DOMException);
void setVariable(in DOMString variableName,
in DOMString value)
raises(DOMException);
readonly attribute unsigned long length;
DOMString item(in unsigned long index);
readonly attribute CSSRule parentRule;
};

Attributes

cssText of type DOMString
The parsable textual representation of the variable declaration block (excluding the surrounding curly braces). Setting this attribute will result in the parsing of the new value and resetting of all the variables in the variable declaration block including the removal or addition of variables.
Exceptions on setting

DOMException

SYNTAX_ERR: Raised if the specified CSS string value has a syntax error and is unparsable.

length of type unsigned long, readonly
The number of variables that have been explicitly set in this variable declaration block. The range of valid indices is 0 to length-1 inclusive.
parentRule of type CSSRule, readonly
The CSS rule that contains this variable declaration block.

Methods

getVariableValue
Used to retrieve the value of a variable if it has been explicitly set within this variable declaration block.
Parameters
variableName of type DOMString
The name of the variable.

Return Value

DOMString

Returns the value of the variable if it has been explicitly set in this variable declaration block. Returns the empty string if the variable has not been set.


No Exceptions
item
Used to retrieve the variables that have been explicitly set in this variable declaration block. The order of the variables retrieved using this method does not have to be the order in which they were set. This method can be used to iterate over all variables in this variable declaration block.
Parameters
index of type unsigned long
Index of the variable name to retrieve.

Return Value

DOMString

The name of the variable at this ordinal position. The empty string if no variable exists at this position.


No Exceptions
removeVariable
Used to remove a variable if it has been explicitly set within this variable declaration block.
Parameters
variableName of type DOMString
The name of the variable.

Return Value

DOMString

Returns the value of the variable if it has been explicitly set for this variable declaration block. Returns the empty string if the variable has not been set.

setVariable
Used to set a variable value within this variable declaration block.
Parameters
variableName of type DOMString
The name of the CSS variable.
value of type DOMString
The new value of the variable.

Exceptions

DOMException

SYNTAX_ERR: Raised if the specified value has a syntax error and is unparsable.


No Return Value

5.4. Changes to interface CSSValue

IDL Definition

interface CSSValue {

// UnitTypes
const unsigned short CSS_INHERIT = 0;
const unsigned short CSS_PRIMITIVE_VALUE = 1;
const unsigned short CSS_VALUE_LIST = 2;
const unsigned short CSS_CUSTOM = 3;
const unsigned short CSS_VARIABLE = 4; // NEW attribute DOMString cssText; // raises(DOMException) on setting readonly attribute unsigned short cssValueType; };
Defined Constants
CSS_VARIABLE: The value is a CSSVariable.

5.5 Interface CSSVariable

The CSSVariable interface represents a call to CSS Variable.

IDL Definition

interface CSSVariable {

readonly attribute DOMString name;
readonly attribute CSSValue value;
};

Attributes

name of type DOMString, readonly
This attribute is used for the name of the variable.
value of type CSSValue, readonly
This attribute is used for the value of the variable.

6. References

6.1. Normative references

6.2. Other references