Copyright © 2008 Apple, Inc. and Disruptive Innovations.
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.
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.
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.
@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.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.
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.
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 {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.
myMargin1: 2em;
}
@variables print {
myMargin1: 2em;
}
.data, div.entry {
margin-left: 30px;
margin-left: var(myMargin1);
}
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 ] ]*
;
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;}
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; };
VARIABLES_RULE
: The rule is a
CSSVariablesRule.The CSSVariablesRule
interface
represents a @variables
rule within a CSS style sheet.
The
@variables
rule is used to specify variables.
interface CSSVariablesRule {
readonly attribute stylesheets::MediaList media;
readonly attribute CSSVariablesDeclaration variables;
};
media
of type
stylesheets::MediaList
, readonlyvariables
of type CSSVariablesDeclaration
,
readonlyCSSVariablesDeclaration
interface
represents a
single block of variable declarations.
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;
};
cssText
of type
DOMString
|
SYNTAX_ERR: Raised if the specified CSS string value has a syntax error and is unparsable. |
length
of type
unsigned long
, readonlyparentRule
of
type CSSRule
,
readonly
.
getVariableValue
variableName
of type
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. |
item
index
of type
unsigned long
|
The name of the variable at this ordinal position. The empty string if no variable exists at this position. |
removeVariable
variableName
of type
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
variableName
of type
DOMString
value
of type
DOMString
|
SYNTAX_ERR: Raised if the specified value has a syntax error and is unparsable. |
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; };
CSS_VARIABLE
: The value is a
CSSVariable.interface CSSVariable {
readonly attribute DOMString name;
readonly attribute CSSValue value;
};
name
of type
DOMString
, readonlyvalue
of type CSSValue
, readonly