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

Переменные SASS: Основы работы

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

С помощью переменных вы можете избавиться от дублирования кода. Посмотрим, как это работает на примере создания цветовой схемы проекта. Возьмём несколько основных цветов, которыми мы хотим пользоваться:

  • Тёмный — #303846
  • Светлый — #f7f7f7
  • Основной — #09d3ac
  • Вторичный — #2196f3

Теперь в начале нашего SASS-файла мы можем объявить переменные и записать эти значения в них. Для этого используется символ $ и указывается уникальное имя.

$dark: #303846;
$light: #f7f7f7;
$primary: #09d3ac;
$secondary: #2196f3;

Теперь мы можем использовать эти цвета в любой части нашего проекта, просто обращаясь к ним по имени.

.card {
  background: $light;
  border: 1px solid $dark;
}

В результате компиляции получится следующий CSS-код:

.card {
  background: #f7f7f7;
  border: 1px solid #303846;
}

Обратите внимание, что также, как и шаблонные селекторы, переменные не попадают в наш CSS-файл после компиляции. Они используются только внутри SASS-файла, что помогает избежать лишней информации внутри CSS.

Многие могут возразить, что переменные уже существуют в CSS и их использование похоже на то, что было описано выше. Вы будете правы — в CSS сейчас возможно управлять цветами точно таким же образом. Но при этом появляются лишние значения и само использование переменных чуть сложнее, чем это происходит в препроцессорах. Также важно понимать разницу переменных в SASS и в CSS. Переменные в CSS существуют в "настоящем времени", то есть они находятся в CSS-файле, их можно менять непосредственно в CSS и браузеры постоянно ссылаются на них, когда это необходимо. Переменные же в SASS исчезают после компиляции, а вместо них в CSS просто подставляются значения.

Область видимости

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

$margin-top: 20px;

.card {
  $bg-color: #f9f9f9;
}

.wrapper {
  margin-top: $margin-top;
  background: $bg-color;
}

В данном случае мы объявили две переменные: $margin-top и $bg-color. Впоследствии обе переменные были использованы в селекторе .wrapper. Что произойдёт после компиляции? На самом деле никакой компиляции не произойдёт. Мы получим сообщение об ошибке:

Error: Undefined variable.
  ╷
9 │   background: $bg-color;
  │               ^^^^^^^^^
  ╵

Компилятор говорит нам, что на 9 строке используется неизвестная переменная. Но ведь она есть — мы её объявили на 4 строке! Да — в коде действительно существует переменная $bg-color, но она существует только внутри селектора .card и вне этого селектора просто невидна.

Такое поведение называется областью видимости переменной. В зависимости от того, где мы объявили переменную, мы можем получать доступ к ней или во всём проекте, или только внутри одного селектора. Переменная $margin-top в этом примере является глобальной переменной, так как доступ к ней есть в любом участке нашего SASS-файла. Переменная $bg-color в примере является локальной переменной и доступна она только внутри того селектора, где была определена.

Разберём ещё один пример:

.card {
  $main-bg: #f9f9f9;
  $header-bg: #2196f3;

  .card-header {
    background: $header-bg;
  }

  .card-body {
    background: $main-bg;
  }
}

Обратите внимание, что переменные $main-bg и $header-bg объявлены внутри селектора .card. Так как селекторы .card-header и .card-body лежат внутри селектора .card, то переменные $main-bg и $header-bg будут доступны для этих селекторов. После компиляции мы получим следующий CSS-код:

.card .card-header {
  background: #2196f3;
}

.card .card-body {
  background: #f9f9f9;
}

Именование переменных

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

$main-bg: #f7f7f7;

.card {
  $main-bg: #f9f9f9;
  $header-bg: #2196f3;

  .card-header {
    background: $header-bg;
  }

  .card-body {
    background: $main-bg;
  }
}

.wrapper {
  background: $main-bg;
}

Заметьте, что переменная $main-bg объявлена и в начале SASS-файла и в селекторе .card. Скорее всего с первого взгляда вы не определите какой $main-bg будет использован в проекте. Попробуем скомпилировать этот код. В этот раз ошибок не будет:

.card .card-header {
  background: #2196f3;
}

.card .card-body {
  background: #f9f9f9;
}

.wrapper {
  background: #f7f7f7;
}

Созданная внутри селектора .card переменная $main-bg на самом деле не имеет ничего общего с глобальной переменной $main-bg. Даже при условии того, что они имеют одинаковые имена. Но вот путаницу это может внести, поэтому никогда не используйте одинаковые имена для глобальных и локальных переменных.

Подключение переменных из другого файла

Часто для удобной организации SASS стили разбиваются на несколько независимых файлов, в зависимости от их назначения. Например, у нас может быть следующая структура файлов:

└── scss/
    ├── config.scss
    ├── default_variables.scss
    └── app.scss

В данной структуре у нас есть главный файл app.scss, в котором мы хотим подключить настройки из файла config.scss и стандартные настройки переменных из файла default_variables.scss. Подключить эти файлы в файл app.scss можно с помощью директивы @import, указав путь к необходимому файлу:

@import "config.scss";
@import "default_variables.scss";

Также при подключении SASS-файлов необязательно указывать расширение. Компилятор найдёт необходимый файл в указанной директории и подключит его. Значит, мы можем немного переписать код и не указывать лишнее расширение:

@import "config";
@import "default_variables";

Порядок подключения файлов в данном случае очень важен. Если внутри файлов config.scss и default_variables.scss будут конфликтующие значения, то возьмётся то, которое было указано последним. Здесь работает то же правило каскадности, что и в CSS: стили, записанные позже, имеют больший приоритет.

Флаг default

Вернёмся к структуре нашего проекта. В default_variables.scss запишем базовые цвета для нашего проекта:

$primary: #A0D788;
$secondary: #71D0A7;
$third: #CCD47D;

Теперь, подключив файл к нашему основному файлу стилей, мы можем использовать эти переменные. Используем цвета в файле app.scss:

@import "config";
@import "default_variables";

.card {
  background: $primary;

  .btn {
    background: $secondary;
  }
}

После компиляции получим следующий CSS-код:

.card {
  background: #A0D788;
}

.card .btn {
  background: #71D0A7;
}

Проходит какое-то время, наш файл с переменными растёт. Возможно, мы даже используем его как пакет во многих проектах (например, похожий файл есть во фреймворке Bootstrap) и вдруг появилось желание изменить базовый цвет. Это абсолютно нормально, и все проекты ждёт такой этап.

Если мы изменим цвет непосредственно в файле default_variables.scss, то получим необходимый нам результат. Но иногда такой подход не работает. Представим, что мы используем такой файл в виде пакета, который загружается извне. В таком случае мы не сможем получать обновления, изменив значение в локальном файле. Наш файл уже не идентичен тому, который расположен на общем сервере.

Решить эту проблему помогает специальный флаг !default. Данный флаг выставляется после значения переменной и говорит о том, что значение по умолчанию необходимо использовать только в том случае, если ранее значение переменной нигде не было указано. Проставим для нашей цветовой схемы флаг !default:

$primary: #A0D788!default;
$secondary: #71D0A7!default;
$third: #CCD47D!default;

Теперь, если мы добавим переменную $primary в файл config.scss, то именно её значение будет использовано в качестве фонового цвета для селектора .card:

config.scss

$primary: #09D3AC;

default_variables.scss

$primary: #A0D788!default;
$secondary: #71D0A7!default;
$third: #CCD47D!default;

app.scss

@import "config";
@import "default_variables";

.card {
  background: $primary;

  .btn {
    background: $secondary;
  }
}

После компиляции этого кода мы получим следующий результат:

.card {
  background: #09D3AC;
}

.card .btn {
  background: #71D0A7;
}

Обратите внимание, что итоговое значение $primary появилось именно из файла config.scss, так как в файле с переменными по умолчанию стоит флаг !default.


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

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

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

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

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

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

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

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

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

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

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff

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

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

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

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