Основы Sass: @-правила и директивы
HTML&CSS

Основы Sass: @-правила и директивы

Оригинал: Sass Basics: @-rules and Directives, Reggie Dawson

@-правила и директивы — ключевые особенности Sass, которые непеременно нужно знать, особенно это касается директивы @import. Некоторые из этих @-правил расширяют @-правила CSS, другие являются специфичными для Sass. В любом случае, вы должны знать эти правила, если собираетесь работать с Sass.

@import

Sass расширяет правило CSS @import, добавляя возможность импортировать файлы SCSS/Sass. Обычно мы используем это правило, чтобы импортировать Sass файлы в основной файл. Импорт файла дает доступ ко всем миксинам и переменным в этом файле.

Sass по умолчанию ищет другие файлы в текущей директории, а потом в директории Sass под Rails. Вы также можете задать дополнительные папки, в которых будут искаться файлы. Например, если вы используете Compass, вы можете задать настройку sass_dir в config.rb.

Директива @import ищет файлы Sass, но будет скомпилирована в CSS директиву @include при следующих условиях:

  • Расширение файла .css
  • Имя файла начинается с http://
  • Имя файла — это url()
  • @import содержит медиа запросы

Если расширение файлы .scss или .sass, файл будет импортирован. Если расширение не указано, Sass попытается найти файл с таким именем и соответствующим расширением. Например:


@import "sample.scss";

@import "sample";

Оба эти выражения валидны, будет импортирован файл sample.scss. Второй @import также подключит файл sample.sass, если он существует.

В одном выражении можно импортировать несколько файлов, перечислив их имена через запятую.


@import "sample1", "sample2", "sample3";

Необходимо соблюдать осторожность при импорте файлов, так как они должны быть импортированы в правильном порядке. Например, если у нас есть файл myVariables, который содержит переменные в проекте и файл myStyles, который использует эти переменные, то файл myVariables должен быть импортирован в первую очередь.


@import "myStyles";
@import "myVariables";

Если мы импортируем файлы в таком порядке, который показан выше, то получим ошибку, т.к. myStyles использует переменные, которые еще не определены.


@import "myVariables";
@import "myStyles";

Это правильный способ, потому что переменные будут импортированы раньше.

Импорт фрагментов

Когда мы импортируем SCSS/Sass файл, он компилируется в отдельный CSS файл с тем же именем. Обычно мы все же хотим собрать все SCSS/Sass файлы в один CSS. Чтобы каждый файл не компилировался в отдельный CSS, файлы можно импортировать как фрагменты, для этого достаточно добавить символ подчеркивания перед именем файла. Подчеркивание говорит Sass, что данный файл не нужно компилировать в отдельный CSS, нужно вставить в текущий файл его содержимое вместо выражения @import.

Когда мы импортируем фрагмент, символ подчеркивания указывать не нужно. Давайте переименуем файл myVariables в _myVariables. Подключается он так же, как и раньше.


@import "myVariables";

Разница в том, что файл myVariables.css не будет создан, содержимое импортируется в основной CSS файл. Важно помнить, что не должно быть фрагмента и отдельного файла в одной и той же директории. Файлы _myVariables.scss и _myVariables.scss должны лежать в разных папках.

Вложенные импорты

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


.try {
  color: blue;
}

Мы можем импортировать этот файл в основной.


#why {
  @import "test";
}

Скомпилированный CSS:


#why .try {
  color: blue;
}

Директивы, такие как @mixin, допустимы только на базовом уровне, их не должно быть файлах, которые импортируются в правила. Также нельзя вызвать @import внутри миксина или управляющей директивы.

@media

Директива @media похожа на директиву @media из CSS, с той лишь разницей, что она может находиться внутри правил. Если директива @media находится внутри правила, при компиляции она всплывает на верхний уровень.


.container {
  width: 60%;
  @media (min-width: 200px) and (max-width:600px) {
    width: 100%;
  }
}

Будет скомпилировано в:


.container {
  width: 60%;
}
@media (min-width: 200px) and (max-width: 600px) {
  .container {
    width: 100%;
  }
}

Мы получили отдельное правило для нашего медиа-запроса, хотя в Sass оно было вложено внутри .container. Также мы можем вкладывать директивы @media друг в друга. Эти запросы будут объединены по И.


@media screen {
  .main {
    @media (max-width: 600px) {
      width: 100%;
    }
    @media (min-width: 700px) {
      width: 70%;
    }
  }
}

Получим:


@media screen and (max-width: 600px) {
  .main {
    width: 100%;
  }
}
@media screen and (min-width: 700px) {
  .main {
    width: 70%;
  }
}

При компиляции получилось два медиа-запроса. Наконец, мы можем использовать переменные, функции и операторы в медиа-запросах.


$format: screen;
$mobile: 500px;
$tablet: 800px;
$desktop: 1200px;

@media #{$format} {
  .menu {
    @media (max-width: $mobile) {
      width: 100%;
    }
    @media (max-width: $tablet) {
      width: 60%;
    }
    @media (max-width: $desktop) {
      width: 30%;
    }
  }
}

В примере выше мы использовали переменную $format и различные переменные для разных типов устройств во вложенных запросах. Получим:


@media screen and (max-width: 500px) {
  .menu {
    width: 100%;
  }
}
@media screen and (max-width: 800px) {
  .menu {
    width: 60%;
  }
}
@media screen and (max-width: 1200px) {
  .menu {
    width: 30%;
  }
}

@extend

Иногда какой-либо элемент на странице должен иметь все стили другого элемента, плюс свои собственные. Допустим, у нас есть два класса для текста, первый для обычного текста, второй для выделения.


.main {
  color:  black;
  font-size: 12px;
}
.emphasis {
  font-weight: bold;
}

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


<div class="main emphasis">

Мы используем Sass, чтобы уменьшить количество кода. Директива @extend позволяет одному классу унаследовать все стили другого.


.master {
  color:  black;
  font-size: 12px;
}
.emphasis {
  @extend .master;
  font-weight: bold;
}

Пример выше будет скомпилирован в:


.master, .emphasis {
  color: black;
  font-size: 12px;
}

.emphasis {
  font-weight: bold;
}

Как вы можете видеть, класс .emphasis включает в себя все стили класса .master, а также имеет свои для выделения текста. Теперь для выделенного текста можно использовать только класс .emphasis.

С помощью директивы @extend можно наследоваться от нескольких селекторов, класс может иметь несколько директив @extend, также они могут образовывать цепочки. Подробнее вы можете посмотреть в документации.

Используйте @extend с осторожностью, так как он может запутывать стили. Хьюго написал пост о том, почему он избегает использования @extend и более подробный пост на ту же тему.

@at-root

Директива @at-root создает правила в корне документа вместо родительского элемента, в котором они указаны.


.top {
  .first {
    font-size: 12px;
  }
  @at-root {
    .second {
      font-size: 14px;
    }
    .third {
      font-size: 16px;
    }
  }
  .fourth {
    font-size: 18px;
  }
}

Будет скомпилировано в:


.top .first {
  font-size: 12px;
}
.second {
  font-size: 14px;
}
.third {
  font-size: 16px;
}
.top .fourth {
  font-size: 18px;
}

Директива @at-root работает как блок селектора. Как видите, правила внутри @at-root скомпилировались в корне документа, а другие селекторы вложены в .top.

Директива @at-root также позволяет вынести селекторы из другой директивы с помощью (without: ...) или (with: ...). Например:


@media print {
  .copy {
    color: black;
    @at-root (without: media) {
      width: 100%;
    }
  }
}

Получим:


@media print {
  .copy {
    color: black;
  }
}
.copy {
  width: 100%;
}

Директива @at-root использовалась с without, поэтому стили скомпилировались без медиа-запроса.

@debug

Директива @debug позволяет вывести значение в стандартный поток вывода. Например:


@debug 10px + 20px;

Когда с сохраню файл, в поток вывода команды watch выведется:


1 DEBUG: 30px

@warn

Директива @warn печатает значение выражение в стандартный поток вывода.


$wrn: 20px;
@warn "#{$wrn}";

Этот код выведет значение выражение и номер строки предупреждения.

@error

Директива @error также позволяет вывести значение выражение в стандартный поток вывода.


$test: 1px;
@error "#{$test}";

Этот код выведет значение выражение и номер строки предупреждения.

Заключение

Мы рассмотрели ряд @-правил и директив, о которых вы могли не знать. Возможно, вы не часто сможете их использовать, но всегда полезно знать, какие инструменты есть в нашем распоряжении.

Рассылка
Подпишитесь на рассылку и получайте дайджест новостей и статей.
Никакого спама!
Подписаться