- Home
- Blog
- Web Design Introduction to CSS Variables
Introduction to CSS Variables
- 6 min. read
-
William CraigCEO & Co-Founder
- President of WebFX. Bill has over 25 years of experience in the Internet marketing industry specializing in SEO, UX, information architecture, marketing automation and more. William’s background in scientific computing and education from Shippensburg and MIT provided the foundation for MarketingCloudFX and other key research and development projects at WebFX.
This guide talks about a subject matter that’s not yet supported in most browsers. See the browser support section for more information.
CSS variables give us many of the same advantages that classic variables offer up to programming languages: convenience, code-reusability, a more readable codebase, and improved mistake-proofing.
Example
:root { --base-font-size: 16px; --link-color: #6495ed; } p { font-size: var( --base-font-size ); } a { font-size: var( --base-font-size ); color: var( --link-color ); }
Basics
There are three main components you should know about when using CSS variables:
- Custom properties
var()
function:root
pseudo-class
Custom Properties
You already know about the standard CSS properties such as color
, margin
, width
, and font-size
. The following example uses the color
CSS property:
body { color: #000000; /* The "color" CSS property */ }
A custom property just means that we (the CSS authors) get to define the property’s name. To define a custom property name, we need to prefix it with two dashes (--
).
If we want to create a custom property with the name of text-color
that has a color value of black (#000000
in hex code), this is how we could do it:
:root { --text-color: #000000; /* A custom property named "text-color" */ }
var() Function
In order to apply our custom properties to our work, we have to use the var()
function, otherwise browsers won’t know what they’re for. If we want to use the value of our --text-color
custom property in our p
, h1
, and h2
style rules, then we need to use the var()
function like this:
:root { --text-color: #000000; } p { color: var( --text-color ); font-size: 16px; } h1 { color: var( --text-color ); font-size: 42px; } h2 { color: var( --text-color ); font-size: 36px; }
The example above is equivalent to:
p { color: #000000; font-size: 16px; } h1 { color: #000000; font-size: 42px; } h2 { color: #000000; font-size: 36px; }
:root Pseudo-class
We need a place to put our custom properties in. We can specify custom properties within any style rule, but many times, that’s not a good idea because specifying custom properties all over the place presents maintainability and CSS-readability challenges.
The :root
pseudo-class represents the top level of our HTML documents. This selector is a good place to put our custom properties in because we can predictably overwrite the custom property values through other CSS selectors that have greater specificity.
Benefits of CSS Variables
Maintainability
Within a given web development project, we’ll often be reusing certain CSS property values.
We’ll often reuse colors, line heights, margins, font sizes and so forth. Here’s an example of four style rules that could benefit from CSS variables:
h1 { margin-bottom: 20px; font-size: 42px; line-height: 120%; color: gray; } p { margin-bottom: 20px; font-size: 18px; line-height: 120%; color: gray; } img { margin-bottom: 20px; border: 1px solid gray; } .callout { margin-bottom: 20px; border: 3px solid gray; border-radius: 5px; }
The problem surfaces when we need to change certain property values later on. If we manually change our values by hand, it might take us a lot of time, and there’s a huge chance we’ll make an error somewhere, especially if our stylesheet is huge.
Similarly, if we perform a batch find-and-replace, we might unintentionally affect other style rules. We can rewrite the above example using CSS variables:
:root { --base-bottom-margin: 20px; --base-line-height: 120%; --text-color: gray; } h1 { margin-bottom: var( --base-bottom-margin ); font-size: 42px; line-height: var( --base-line-height ); color: var( --text-color ); } p { margin-bottom: var( --base-bottom-margin ); font-size: 18px; line-height: var( --base-line-height ); color: var( --text-color ); } img { margin-bottom: var( --base-bottom-margin ); border: 1px solid gray; } .callout { margin-bottom: var( --base-bottom-margin ); border: 1px solid gray; border-radius: 5px; color: var( --text-color ); }
Now imagine your client says to you that the text on the screen is hard to read because the text color is too light. In this situation, we just need to update one line in our CSS:
--text-color: black;
That’s -66% fewer lines of code we have to edit, in the context of the previous set of style rules (one line versus three lines) .
In the same token, using CSS variables gives us an easier time when we want to experiment with our designs. While we’re developing the project, we can rapidly test color values, line-heights, and bottom-margin values all in one place, and we’ll be able to see the effects in a holistic way.
Improved CSS Readability
Custom properties can help make our stylesheets easier to read.
It could make our CSS property declarations more meaningful as well. Compare this:
background-color: yellow; font-size: 18px;
To this:
background-color: var( --highlight-color ); font-size: var( --base-font-size );
Property values like yellow
and 18px
don’t give us any useful contextual information. But when we read custom property names like --base-font-size
and --highlight-color
, even when we’re reading someone else’s code, we instantly know what the property value is doing.
Things to Keep in Mind
Case-sensitivity
Custom properties are case-sensitive (unlike regular CSS properties).
:root { --main-bg-color: green;--MAIN-BG-COLOR: RED; } .box { background-color: var( --main-bg-color ); /* green background */ } .circle { BACKGROUND-COLOR: VAR(--MAIN-BG-COLOR ); /* red background */ border-radius: 9999em; } .box, .circle { height: 100px; width: 100px; margin-top: 25px; box-sizing: padding-box; padding-top: 40px; text-align: center; }
In the above example, there are actually two custom properties that have been defined: --main-bg-color
and --MAIN-BG-COLOR
.
Custom Property Value Resolution
When a custom property is declared more than once, the assignment follows normal CSS cascading and inheritance rules.
In the following example, the link will be assigned the color of red
because the .container
selector has greater specificity compared to :root
and body
. HTML
<body> <div class="container"> <a href="">Link</a> </div> </body>
CSS
:root { --highlight-color: yellow; } body { --highlight-color: green; } .container { --highlight-color: red; } a { color: var( --highlight-color ); }
However, if we remove the .container
style rule from our code, the link will be assigned the color of green
because body
now becomes the next selector that matches our links.
Fallback Values
You can assign a fallback property value when using the var()
function notation.
Simply provide the fallback property value as an additional argument delineated with a comma (,
). In the following example, the .box
element is supposed to be rendered with a black background. However, because there’s a typo when referencing the custom property name, the background will be rendered using the fallback value (i.e.
red
). HTML
<div class="box">A Box</div>
CSS
div { --container-bg-color: black; } .box { width: 100px; height: 100px; padding-top: 40px; box-sizing: padding-box; background-color: var( --container-bf-color, red ); color: white; text-align: center; }
Invalid Values
Beware of assigning CSS properties with the wrong type of value. In the following example, since the --small-button
custom property is given a length unit, its use within the .small-button
style rule is invalid.
:root { --small-button: 200px; } .small-button { color: var(--small-button); }
A good way to avoid this situation is to come up with descriptive custom property names. For instance, naming the above custom property --small-button-width
makes its improper use unlikely.
Browser Support for CSS Variables
Last updated: March 2015.
Desktop
Browser | Version Support |
---|---|
Chrome | None |
Firefox | Version 31 |
IE | None |
Safari | None |
Mobile
Browser | Version Support |
---|---|
Chrome (Android) | None |
Safari (iOS) | None |
Information covered in this guide uses the latest version of W3C CSS Custom Properties for Cascading Variables Module Level 1 as a reference.
Related Content
- Introduction to CSS Colors
- Why the :visited Pseudo-class is Strange
- CSS Link Pseudo-classes
- A Quick Overview of CSS calc()
Jacob Gube is the founder of Six Revisions. He’s a front-end developer. Connect with him on Twitter.
-
President of WebFX. Bill has over 25 years of experience in the Internet marketing industry specializing in SEO, UX, information architecture, marketing automation and more. William’s background in scientific computing and education from Shippensburg and MIT provided the foundation for MarketingCloudFX and other key research and development projects at WebFX.
-
WebFX is a full-service marketing agency with 1,100+ client reviews and a 4.9-star rating on Clutch! Find out how our expert team and revenue-accelerating tech can drive results for you! Learn more
Make estimating web design costs easy
Website design costs can be tricky to nail down. Get an instant estimate for a custom web design with our free website design cost calculator!
Try Our Free Web Design Cost CalculatorWeb Design Calculator
Use our free tool to get a free, instant quote in under 60 seconds.
View Web Design CalculatorMake estimating web design costs easy
Website design costs can be tricky to nail down. Get an instant estimate for a custom web design with our free website design cost calculator!
Try Our Free Web Design Cost Calculator