Взгляните на следующие 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
так как унаследовали значение переменной от общего стиля.
Это может выглядеть очень запутанно, и, на самом деле, так и есть! В большинстве случаев разработчики стараются использовать исключительно глобальные переменные, так как:
- Они находятся в одном месте
- В любом месте проекта можно быстро понять, чему равна та или иная переменная
Стоит ли забыть про локальные переменные? Нет! Они так же активно используются, но в рамках глобальных изменений. Например, при реализации светлой и темной темы. Глобально может быть установлена светлая тема, а для класса с темной темой эти переменные переопределяются. Такой вариант вполне очевиден и не привносит дополнительных проблем, так как переменные переопределяются все сразу.
Значение переменных по умолчанию
При использовании функции var()
можно указать не только имя переменной, но и значение по умолчанию, если вдруг в переменной ничего нет. Ситуация не настолько частая, но знать про такую особенность важно.
.section {
background: var(--bg, #fff);
}
Если переменной --bg
нет, то в качестве значения будет использовано значение #fff
.
Самостоятельная работа
Перейдите во все доступные CodePen в уроке и попробуйте создать разные переменные. Особенно важно поработать с локальными переменными
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.