Зарегистрируйтесь, чтобы продолжить обучение

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>

Другой пример:

:root {
 --padding: 10px;
}

p {
  --padding: 20px 30px;
}

.main-section {
  padding: var(--padding);

  background: #ffca28;
}

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

  background: #ff9800;
}
<!-- Блок с правилом padding: 10px -->
<div class="main-section">
  <!-- Параграф с правилом padding: 20px 30px -->
  <p class="paragraph">Параграф с текстом и внутренними отступами. padding: 20px 30px</p>
</div>

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

Оба параграфа получили свойство padding: 20px 30px так как унаследовали значение переменной от общего стиля.

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

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

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

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

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

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

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


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

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


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

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

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

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

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

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

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

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

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

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

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

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

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
Верстка на HTML5 и CSS3, Программирование на JavaScript в браузере, разработка клиентских приложений используя React
10 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на Python, Разработка веб-приложений и сервисов используя Django, проектирование и реализация REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на Java, Разработка веб-приложений и микросервисов используя Spring Boot, проектирование REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на PHP, Разработка веб-приложений и сервисов используя Laravel, проектирование и реализация REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на JavaScript в браузере и на сервере (Node.js), разработка бекендов на Fastify и фронтенда на React
16 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на JavaScript, разработка веб-приложений, bff и сервисов используя Fastify, проектирование REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
новый
Git, JavaScript, Playwright, бэкенд-тесты, юнит-тесты, API-тесты, UI-тесты, Github Actions, HTTP/HTTPS, API, Docker, SQL
8 месяцев
c опытом
Старт 26 декабря

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

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

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

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»