CSS variables, or “CSS Custom Properties”. It allows you to work with variables directly in CSS. They are very useful for reducing repetition in CSS, and also for powerful runtime effects like theme switching and has a various polyfilling future CSS features. It believes in the principle DRY — Don’t Repeat Yourself. With the help of CSS Variables, you can localize values and simplify initial development, iterative testing, and later maintenance all in one go. It is also officially a part of the CSS specification. So, let’s explore.

Basic declaration

Any CSS property -- color, size, position, etc. -- can be stored in a CSS variable. Their names are all prefixed with -- , and you declare them by adding them to an element right where you add its other styles:

For example:

/* Define CSS variables and scope */ :root {

--maincolor: black;

--secondarycolor: red;

} /* Use CSS Variables */ body {

background: var(--maincolor);

color: white;

} body p {

background: var(--secondarycolor);

}

Here I’ve defined two CSS variables which have color values inside the :root selector. The variables are defined inside and are scoped with their respective selectors. Note that CSS variables are case sensitive unlike other CSS properties, so --maincolor and --Maincolor are considered two different variables.

And to use a CSS variable, we need to wrap its value in the var() function and pass the variable name into it. After that, we can select the desired CSS property and utilize this variable's value.

For example:

a {

color: var(--maincolor);

text-decoration-color: var(--secondarycolor);

}

Another cool feature of CSS Variables is we can even set one CSS variable’s value to another CSS variable in whole or in part:

For Example:

/* Define CSS variables and scope */ :root {

--darkfont: green;

--darkborder: 5px dashed var(--darkfont);

} /* Use CSS Variables */ .container {

color: var(--darkfont);

border: var(--darkborder);

}

Scoping and the Cascade

CSS variables act like a normal style property; a variable is available anywhere down the cascade.

For example, these variables can be used by anything on the entire page:

root {

--darkborder: 5px solid black;

} body {

--darkborder: 1px solid darkred;

} img{

border: var(--darkborder); /* img border will be 1px solid darkred */

}

Here we have defined the same --darkborder CSS variable twice inside two different selectors. Due to cascading rules, the one inside the BODY selector has a higher specificity, and wins out when used in the IMG element.

CSS Variables also inherit by default, so the value of a CSS property defined on a parent element also applies down to the children when used in those elements.

For example:

:root {

--myborder: 2px solid black;

} ul {

margin: 0;

border-left: var(--myborder);

} ul ul {

margin-left: 30px;

}

But we can also disable the inheritance property by setting it to the special value “ initial " inside the desired selector. From the above example

:root {

--myborder: 2px solid black;

} ul {

margin: 0;

border-left: var(--myborder);

} ul ul {

--myborder: initial; /* reset --myborder variable */

margin-left: 30px;

}

Advantages in Media Queries

We can use this type of pattern for the CSS Variables media queries where all change is happening in-browser, and the variables do know about the conditions under which they are being used. And this prevents us from the repetition of the selectors rather than the properties.

For Example:

body {

--primary: #7F583F;

--secondary: #F7EFD2;

} a {

color: var(--primary);

text-decoration-color: var(--secondary);

} @media screen and (min-width: 480px) {

body {

--primary: #F7EFD2;

--secondary: #7F583F;

}

}

Simple Demo:

Setting fallback values when a CSS variable is undefined

background: var(--primarybg, white);

/* Normal value as fallback value */ font-size: var(--defaultsize, var(--fallbacksize, 36px));

/* var() as fallback value */

To provide fallback values for browsers that don’t support the feature, you could do something like the following:

background: white;

/* background value for browsers that don't support CSS variables */ background: var(--primarybg, white);

Everyone will be happy now !

Browser Support