Sass

SCSS

Что это такое

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

Почему это важно

Много лет подряд Sass был способом выжить с таблицей стилей длиннее нескольких сотен строк, и изрядная доля продакшен-CSS до сих пор собирается так. Многие его возможности с тех пор поглотил сам CSS — пользовательские свойства, нативная вложенность, color-mix(), — и от этого зависит, для чего кодовой базе на Sass вообще стоит его использовать. Если понимать, какие части стали избыточными, шаг сборки не придётся тащить без причины, а если понимать, какие не стали, большая существующая кодовая база останется сопровождаемой.

Ключевые идеи

Партиалы и @use организуют, не протекая наружу

Партиал — файл, чьё имя начинается с подчёркивания. @use загружает его один раз, под пространством имён, и его члены видны там, где нужны; на смену более старому @import он пришёл потому, что тот загружал один и тот же файл повторно и сваливал каждую переменную в общую глобальную область видимости, а @use этого не делает.

// _scale.scss
$step: 0.25rem;

@function spacing($n) {
  @return $step * $n;
}

// card.scss
@use "scale";

.card { padding: scale.spacing(4); }

Миксины — для блоков правил, функции — для значений

Миксин испускает объявления и умеет принимать аргументы, функция возвращает значение; повторяющийся градиент или стиль фокуса — работа для миксина, а вычисление шага отступа или контрастно-безопасного цвета — работа для функции. Стоит держать это различие, и тогда по месту вызова сразу видно, что именно ему нужно.

@mixin focus-ring($color: currentColor) {
  outline: 3px solid $color;
  outline-offset: 2px;
}

.button:focus-visible { @include focus-ring(teal); }

Вкладывайте сдержанно

Вложенность Sass — удобство, а не разрешение: каждый уровень повышает специфичность скомпилированного селектора, а глубокая вложенность порождает селекторы, которые не переопределить без ещё одного уровня. Устойчивый предел — вложить один уровень и использовать & для состояния или модификатора.

.card {
  padding: 1rem;

  &.is-selected { border-color: teal; }
}

Знайте, что CSS теперь делает бесплатно

Большинство случаев применения переменных закрыли пользовательские свойства: они существуют во время выполнения и меняются для поддерева, а структурную вложенность заменила нативная. clamp(), min(), max() и color-mix() взяли на себя многие функции. По-настоящему уникальной остаётся машинка времени компиляции: циклы по карте, которые порождают систематический набор утилит, и функции, которые дают значения, каких CSS вычислить не может.

$sizes: (sm: 0.75rem, md: 1rem, lg: 1.5rem);

@each $name, $size in $sizes {
  .button--#{$name} { font-size: $size; }
}

Порядок компиляции и размер вывода — реальные заботы

Из малого исходника Sass способен породить большой объём CSS: цикл по карте цветов и размеров краток в написании и дорог в доставке. Проверяйте скомпилированный вывод и выбирайте сборку, которая испускает только то, что использует страница.

Практика

Замените переменную Sass пользовательским свойством

Возьмите переменную Sass для фирменного цвета и перенесите её в пользовательское свойство CSS, а затем поменяйте её для одного поддерева без перекомпиляции.

Готово, когда: цвет можно поменять во время выполнения, задав свойство на контейнере, и ни одна переменная Sass больше не дублирует значение.

Сгенерируйте набор утилит из карты

Напишите цикл Sass, который порождает модификаторы размера кнопки из карты с тремя шагами. Затем сравните размер получившегося вывода с тремя правилами, написанными вручную.

Готово, когда: цикл порождает те же правила, что и рукописная версия, а вы можете объяснить, когда меньший исходник цикла оправдывает больший вывод.

Частые ошибки

  • Глубокая вложенность в угоду разметке — скомпилированные селекторы набирают специфичность, и переопределить их становится нечем; исправить: вкладывайте один уровень и используйте & для состояний.
  • Переменная Sass там, где подходит пользовательское свойство — значение фиксируется во время сборки и не поддаётся темизации; исправить: берите пользовательское свойство для всего, что меняется во время выполнения.
  • Подключение партиала, который испускает правила, в нескольких местах — одни и те же объявления дублируются в выводе; исправить: используйте @use и подключайте партиалы с правилами один раз.
  • Генерация всех комбинаций в таблицу стилей — цикл по цветам и размерам может утроить объём CSS; исправить: проверяйте размер компиляции и генерируйте только используемое.
  • Таскание Sass ради возможностей, которые уже есть в CSS — шаг сборки остаётся без выгоды; исправить: проведите ревизию файла и уберите то, что нативная вложенность и пользовательские свойства уже покрывают.

Что читать дальше

  • Каскадные таблицы стилей (CSS) (02-frontend/05-css) — каскад, специфичность и современные возможности, от которых зависит, что всё ещё стоит компилировать.
  • Современные возможности CSS (02-frontend/05-css/04-modern-css) — нативные замены нескольким возможностям Sass.
  • Webpack (02-frontend/24-webpack) — шаг сборки, который исторически компилирует таблицы стилей.