Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

CSS Variables Основы вёрстки контента

Взгляните на следующие CSS-правила:

.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;
}

В правилах трижды используется один и тот же цвет фона #ccc, который установлен у свойства background-color. Скорее всего эти из одной цветовой палитры и дизайнер предполагал, что фоновый цвет блоков должен быть одинаковый. Проходит время, проект растёт, таких блоков становится больше, у них добавляются другие одинаковые свойства, а потом приходит новый дизайнер и решает всё поменять. Если блока всего три, то ничего страшного, а если цветовая схема состоит из 10-20-30 различных цветов и надо быстро их поменять во всём проекте?

Когда-то разработчики решили, что хорошо бы иметь цвета или другие шаблонные значения в одном месте, например, в начале проекта. Логика проста: нужно что-то изменить? Меняется одно значение и в проекте автоматически вносятся изменения. Ранее это было возможно только в рамках специальных программ-препроцессоров, таких как Sass, которые поддерживали переменные — специальные конструкции, которые позволяют хранить нужное нам значение. Сегодня такие переменные изначально доступны в CSS и для их использования не требуется иметь специальные препроцессоры.

Переменные записываются по шаблону: --имя-переменной: значение;. Благодаря этому цвет фона из прошлого примера можно записать так: --main-background: #ccc;. Но куда это вставлять? Для начала используем специальный псевдокласс :root, который позволит вынести переменную для всего проекта, то есть в глобальную область видимости. Про другие области мы поговорим чуть позже. Итоговый код с переменной в глобальной области видимости будет выглядеть так:

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

Как же её использовать? Вначале это может показаться не очень удобным, но внутри CSS есть функция var(), которая принимает имя переменной и подставляет её значение «как есть». Что вы укажете в переменной, то и подставится, даже если значение неправильное. Заменим в прошлом примере все значения background-color на 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;
}

Теперь, чтобы одновременно поменять фон во всех блоках достаточно изменить значение переменной --main-background.


Важно: имя для переменной вы выбираете сами. Тут CSS не накладывает сильных ограничений. Вы можете использовать латинские символы в любом регистре, цифры, подчёркивание и тире. Обратите внимание, что регистр имеет значение. Переменные --color и --Color — две разные переменные


Области видимости переменной

В прошлом примере был использован псевдокласс :root, который позволил установить переменные для всего проекта сразу, но сами переменные можно указать в любом месте проекта, например для определённого блока.

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

  padding: var(--padding);
}

В этом примере переменная --padding доступна только для блока с классом main-section и всех его потомков

<div class="main-section">
  <p class="paragraph">Параграф с текстом</p>
</div>
.main-section {
  --padding: 20px 30px;

  padding: var(--padding);
}

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

Внутренние отступы будут установлены и для элемента <div class="main-section"> и для <p class="paragraph">, так как он находится внутри main-section. Такие переменные имеют локальную область видимости, то есть они видны только в рамках того элемента, у которого и была установлена переменная. Проверить это легко — достаточно добавить ещё один элемент с классом paragraph, который будет лежать вне main-section:

<div class="main-section">
  <!-- Параграф с внутренними отступами -->
  <p class="paragraph">Параграф с текстом</p>
</div>

<!-- Параграф без внутренних отступов -->
<p class="paragraph">Другой параграф</p>
.main-section {
  --padding: 20px 30px;

  padding: var(--padding);
}

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

See the Pen css_content_course_variables_1 by Hexlet (@hexlet) on CodePen.

Свойство padding: 20px 30px будет установлено только для элемента с классом paragraph, который находится внутри элемента с классом main-section. Таким же образом можно и переопределять значения для глобальных переменных, указав новое значение в локальной области видимости:

:root {
 --padding: 10px;
}

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

  padding: var(--padding);
}

.paragraph {
  padding: var(--padding);
}
<div class="main-section">
  <!-- Параграф с правилом padding: 20px 30px -->
  <p class="paragraph">Параграф с текстом</p>
</div>

<!-- Параграф с правилом padding: 10px -->
<p class="paragraph">Другой параграф</p>

Это может выглядеть очень запутанно, и, на самом деле, так и есть! В большинстве случаев разработчики стараются использовать исключительно глобальные переменные, так как:

  1. Они находятся в одном месте
  2. В любом месте проекта можно быстро понять чему равна та или иная переменная

Стоит ли забыть про локальные переменные? Нет! Они так же активно используются, но в рамках глобальных изменений. Например, при реализации светлой и тёмной темы. Глобально может быть установлена светлая тема, а для класса с тёмной темой эти переменные переопределяются. Такой вариант вполне очевиден и не привносит дополнительных проблем, так как переменные переопределяются все сразу.

Значение переменных по умолчанию

При использовании функции var() можно указать не только имя переменной, но и значение по умолчанию, если вдруг в переменной ничего нет. Ситуация не настолько частая, но знать про такую особенность важно.

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

Если переменной --bg нет, то, в качестве значения будет использовано значение #fff


Самостоятельная работа

Перейдите во все доступные CodePen в уроке и попробуйте создать разные переменные. Особенно важно поработать с локальными переменными


Дополнительные материалы

  1. Спецификация CSS Custom Properties for Cascading Variables Module Level 1

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Фронтенд-разработчик
Профессия
Разработка фронтенд-компонентов веб-приложений
30 июня 10 месяцев
Иконка программы Верстальщик
Профессия
Вёрстка с использованием последних стандартов CSS
в любое время 5 месяцев
Иконка программы Fullstack-разработчик
Профессия
Новый
Разработка фронтенд и бэкенд компонентов веб-приложений
30 июня 16 месяцев

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Изображение Тото

Задавайте вопросы, если хотите обсудить теорию или упражнения. Команда поддержки Хекслета и опытные участники сообщества помогут найти ответы и решить задачу