CSS Variables

W3C Proposal, 22 June 2010

This Version:
http://oocss.org/spec/css-variables.html
Latest Version:
http://oocss.org/spec/css-variables.html
Revision:
Revision 1.0
Authors:
Nicole Sullivan

Contents

Declaring variables with the @variables rule

The '@variables' rule allows document authors to link equivalent values throughout one or more stylesheets to a single location in memory. Variable name identifies a specific variable. The variable name is an identifier.

A variable declaration is either empty or consists of a variable name, followed by a colon (:), followed by a value. Around each of these there may be white space. Multiple declarations for the same selector may be organized into semicolon (;) separated groups.

The following fragment defines a variable "myVariable" and assigns it the color value blue:

myVariable: blue;

Variable groups

Variables are contained within the ruleset of a variable group. To define a variable group the '@variables' keyword must be followed by the variable group name and a declaration block. The variable group name is an identifier.

The following lines define a variable group named "color":

@variables color {
  myVariable: blue;
}

The following rule defines three variables; "base", "highlight", and "page" within the "color" variable group.

@variables color {
  base: #e2e2e2;
highlight: #fe8d12; page: #fff;

}

The variable group name is optional, any variable declared in the global scope is treated as though it were in the variable group var.

@variables var {
  globalReset: 0px;
}

Is equivalent to:

@variables {
  globalReset: 0px;
}

Resolving duplicates via the cascade

If a variable is declared twice, the latter definition takes precedence according to the normal rules of the cascade.

In the following example, "base" would be red:

@variables color {
  base: blue;
base: red;

}

When the same @variables group is defined twice, user agents must resolve duplicates according to normal cascade order.

The following example defines a variable group name twice. The variables "x-sm" and "x-lg" are added to the definition of the "spacing" variable group:

@variables spacing {
  sm: 10px;
med: 20px;
lg: 30px;
}
@variables spacing { x-sm: 5px; x-lg: 40px;
}

When the same variable name and group name are defined twice, user agents give the latter definition precedence according to normal rules of the cascade.

The following example defines a new value for the "sm" variable. The new value, "7px", supersedes the previous value.

@variables spacing {
  sm: 10px;
}
@variables spacing { sm: 7px;
}

Variables and shorthand properties

CSS variables may also represent shorthand property value pairs. Such variables may be used in any shorthand property which accepts those values.

The following lines demonstrate a variable "default" in the "contour" variable group:

@variables contour {
  default: solid 10px blue;
}

Media dependent variable groups

Authors may specify media-dependent @variables groups. These conditional variables specify comma separated media types after the URI.

The following lines illustrate how @variables groups can be made media-dependent:

@variables color @media print {
  myVariable: blue;
}

In the absence of any media types, the variables rule is unconditional. Specifying 'all' for the medium has the same effect. The variables only take effect if the target medium matches the media list. A target medium matches a media list in the same cases that it would for @import.

Referencing a variable

Variables are invoked using the notation <variable group name>.<variable name>. User agents should ignore property value pairs if the variable has not been defined according to the normal rules for invalid constructs and, if the UA provides an API to the document author, it should issue a warning.

The following lines demonstrate how a the value of the background-color property can be replaced with a variable "highlightColor" in the "hex" variable group:

.sidebar li a {
background-color: color.highlight;
}

A variable may also replace a portion of a property value.

The following lines demonstrate how one of the values of the background property can be replaced with a variable:

.sidebar li a {
background: color.highlight url(background.png) no-repeat 0 0;
}

The value of a variable must conform to the core grammar and match the allowed values for the property in which it is invoked; otherwise, as for property declarations, the declaration is invalid and must be ignored.

Processing variables

Variables are processed at parse time, after tokenization.

The UA maintains a table of name-value mappings. The name-value tables for each variable group are independent. The UA adds or replaces definitions as it encounters @variables blocks.

Upon encountering a variable reference, the UA validates the value. The normal rules for ignoring invalid constructs apply. If a variable is used before being declared, then it is ignored. The value is stored as a link to the variable definition in the variable table. For that reason, when a variable is updated, all references to that variable are also updated.

In the following example, when the variable "accent" is changed from green to yellow, both "sharpie" and "note" become yellow because their value points to the same location in memory.

@variables color {
  accent: green;
}
.sharpie { background-color: color.accent; }
@variables color { accent: yellow; }
.note { background-color: color.accent; }

Variables may not change type. For example a variable that defines a color may only be updated to define a different color. It may not, for example, be updated to a pixel value. Before the variable table is updated, the new value is validated to insure it matches the previous value. If the value-type does not match, the user agent must ignore the request to update the variable table.

Variables and Specificity

Variables do not impact specificity.

Programmatic access to variables

User agents must provide programmatic access to the variable tables via both name and index. @@@Look at the CSSOM docs for wording here@@@

document.styleSheetVars.<variable-group>.<variable-name>

The following example returns the value of the highlight variable in the color group:

document.styleSheetVars.color.highlight;

The same variable may also be accessed via its index.

The following example would return the first value in the color variable group:

document.styleSheetVars.color[0];

Variable groups can also be accessed via their index. @@@does this return the value or the variable-name: value?@@@

The following example returns the first variable group:

document.styleSheetVars[0];

Each object also provides a length property which returns and integer corresponding to the number of variables or variable groups. Length is not a valid variable group or variable name.

document.styleSheetVars.length;
document.styleSheetVars.color.length;

Acknowledgements

Inspiration for this document came from the W3C CSS Specifications, CSS Variables by Daniel Glazman (Disruptive Innovations) and David Hyatt (Apple, Inc.), CSS Constants by fantasai, Less CSS, Chris Eppstein, Compass, SASS, css-discuss, www-style, and the many web developers clamoring for the tools they need to do their jobs well.

Thanks also to the many people who have provided feedback for this document in it's various incarnations, including; David Hyatt, Tom Croucher, Nicholas Zakas, Stoyan Stefanov, Eric Schurman, Douglas Crockford, Aaron Gustafson, Fred Sauer, Hugo Haas, Brad Neuberg, John Allsopp, Tom Hughes-Croucher, Chris Mills, Doug Schepers, Chris Blizzard, Boris Zbarsky, David Baron, William Cook, David Federman, and Peter-Paul Koch.