Register to get access to free programming courses with interactive exercises

CSS Variables Content layout fundamentals

Take a look at the following CSS rules:

.header {
  display: flex;
  width: 100%;
  height: 50px;

  font: 18px/1.5, sans-serif;

  background-color: #ccc;
}

main {
  margin-top: 50px;
  padding: 20px 30px;

  background-color: #ccc;
}

footer {
  margin-top: 150px;
  padding: 50px;

  background-color: #ccc;
  border: 1px solid #fff;
}

The rules use the same background color, #ccc, three times. This is the value of the background-color property. Most likely these colors are related, and the designer assumed that the background color of the blocks should be the same. As time passed and the project grew, more of these blocks appeared with other identical properties, and then a new designer came and decided to change everything. What if the color scheme consists of 10, 20, or 30 different colors, and you need to change them throughout the project quickly?

At some point, developers decided that it was a good idea to have all colors or other template values in one place, such as at the beginning of a project. The logic is simple; if you need to change something, then you can change one value and the whole project will change automatically. Previously, this was only possible within special preprocessor programs such as Sass, which supported variables – special constructs that allow us to store the value we want. Today, such variables are natively available in CSS, and you don't need special preprocessors to use them.

Variables are written like so: -variable-name: value;. Because of this, the background color from the previous example can be written as follows: --main-background: #ccc;. But where should you put it? First, we use a special pseudo-class, :root, which will allow us to declare a variable for the whole project, i.e., in the global scope. We'll talk about other scopes later. The final code with the variable in the global scope will look like this:

:root {
  --main-background: #ccc;
}

So how do you use it? This may not seem very convenient at first, but inside CSS there is a function called var(), which takes a variable name and substitutes its value as is. What you put in the variable will be substituted, even if the value is wrong. Replace all background-color values in the previous example with var(--main-background).

:root {
  --main-background: #ccc;
}

.header {
  display: flex;
  width: 100%;
  height: 50px;

  font: 18px/1.5, sans-serif;

  background-color: var(--main-background);
}

main {
  margin-top: 50px;
  padding: 20px 30px;

  background-color: var(--main-background);
}

footer {
  margin-top: 150px;
  padding: 50px;

  background-color: var(--main-background);
  border: 1px solid #fff;
}

Now, you can change the value of the --main-background variable to change the background in all blocks at once.


Note: the name of the variable is up to you. CSS doesn't impose any strong restrictions here. You can use upper and lowercase Latin letters, underscores, and dashes. Note that the case does matter. The --color and --Color variables are two different variables


Variable scope

In the last example, the :root pseudo-class was used to set variables for the whole project at once, but the variables themselves can be defined anywhere in the project, for example, for a certain block.

.main-section {
  --padding: 20px 30px;

  padding: var(--padding);
}

In this example, the --padding variable is only available for the block with the main-section class and all its descendants.

<div class="main-section">
  <p class="paragraph">Text paragaraph</p>
</div>
.main-section {
  --padding: 20px 30px;

  padding: var(--padding);
}

.paragraph {
  padding: var(--padding);
}

Padding will be set for both the <div class="main-section"> element and the <p class="paragraph"> element, since it's inside the main-section. Such variables have a local scope, meaning that they're only visible within the element where the variable was set. It's easy to check, just add another element with the paragraph class, which will be located outside of main-section:

<div class="main-section">
  <!-- Paragraph with padding -->
  <p class="paragraph">Text paragaraph</p>
</div>

<!-- Paragraph without padding -->
<p class="paragraph">Another paragraph</p>
.main-section {
  --padding: 20px 30px;

  padding: var(--padding);
}

.paragraph {
  padding: var(--padding);
}

The property padding: 20px 30px will only be set for the element with the paragraph class that's located inside the element with the main-section class. In the same way, you can redefine values for global variables by specifying a new value in the local scope:

:root {
 --padding: 10px;
}

.main-section {
  --padding: 20px 30px;

  padding: var(--padding);
}

.paragraph {
  padding: var(--padding);
}
<div class="main-section">
  <!-- Paragraph with padding: 20px 30px -->
  <p class="paragraph">Text paragaraph</p>
</div>

<!-- Paragraph with padding: 10px -->
<p class="paragraph">Another paragraph</p>

It may look very confusing, and indeed it is! In most cases, developers try to use only global variables because:

  1. They're all in the same place
  2. You can quickly figure out a variable value in any place in the project

So, should we forget about local variables? No! They're just as actively used, but as part of global changes instead. For example, when implementing light and dark modes. You can set light mode globally, and then these variables will be redefined for the dark mode class. This option is quite obvious and doesn't introduce any additional problems because the variables are redefined all at once.

Default variable values

When using the var() function, you can specify not only the variable name but also a default value in case the variable is suddenly empty. Although the case isn't frequent, it's crucial to be aware of this feature:

.section {
  background: var(--bg, #fff);
}

If there is no --bg variable, the value will be #fff.


Do it yourself

Go to all the available CodePens in the lesson and try to create different variables. Working with local variables is particularly important


Recommended materials

  1. Spec on CSS Custom Properties for Cascading Variables Module Level 1

Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
130
courses
1000
exercises
2000+
hours of theory
3200
tests

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending this form, you agree to our Personal Policy and Service Conditions

Our graduates work in companies:

Bookmate
Health Samurai
Dualboot
ABBYY
Suggested learning programs
profession
Development of front-end components for web applications
10 months
from scratch
Start at any time
profession
Layout with the latest CSS standards
5 months
from scratch
under development
Start at any time

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending this form, you agree to our Personal Policy and Service Conditions
Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.