Расширения в Sass

Общие свойства

Иногда вам приходится писать один и тот же набор свойств в разных правилах CSS.

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

Как бы это выглядело в вашем CSS? Вы можете:

  • использовать общий класс CSS, вроде .small-uppercase;
  • группировать селекторы;
  • использовать расширение Sass.

Общий класс CSS

.small-uppercase {
  color: lightslategrey;
  font-size: 10px;
  letter-spacing: 0.1em;
  line-height: 12px;
  text-transform: uppercase;
}

Использование правила CSS .small-uppercase семантически некорректно, потому что вы в конечном итоге пишете ваш HTML как <p class="small-uppercase">, что возвращает, в целом, к написанию стилей в вашем HTML.

Группирование селекторов

Поскольку правило CSS может принимать любое количество селекторов, вы могли бы группировать общие свойства в виде списка селекторов:

.button,
.navigation a,
.sidebar h3,
.tabs a {
  color: lightslategrey;
  font-size: 10px;
  letter-spacing: 0.1em;
  line-height: 12px;
  text-transform: uppercase;
}

Этот подход остаётся семантически корректным, потому что каждый селектор описывает элемент HTML, к которому он прикрепляется.

Тем не менее, есть две проблемы:

  • это правило CSS может стать неуправляемым, как только список селекторов становится больше;
  • поскольку каждый селектор содержит свои собственные специфические правила, вы разделяете свой набор свойств на два (.button может содержать дополнительные правила дальше в CSS).

Sass помогает решить эти проблемы.

Синтаксис @extend

@extend в Sass позволяет наследовать свойства CSS от другого селектора:

// SCSS
.small-uppercase {
  color: lightslategrey;
  font-size: 10px;
  letter-spacing: 0.1em;
  line-height: 12px;
  text-transform: uppercase;
}
  
.modal-background {
  @extend .small-uppercase;
}

.product-link {
  @extend .small-uppercase;
}

.image-pattern {
  @extend .small-uppercase;
}

// Генерируемый CSS
.small-uppercase,
.modal-background,
.product-link,
.image-pattern {
  color: lightslategrey;
  font-size: 10px;
  letter-spacing: 0.1em;
  line-height: 12px;
  text-transform: uppercase;
}

@extend перегруппирует общие свойства под списком селекторов.

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

Ваш HTML остаётся семантическим, поскольку каждый элемент сохраняет своё описательное имя класса.

Отличие от примесей

Итак, вы могли бы думать: «Подождите, это же тогда как примеси?».

Есть два отличия.

  • У правила @extend нет параметров. У примесей есть.
  • Правило @extend группирует селекторы. Примеси нет.

Давайте повторно используем нашу примесь, а также напишем правило .overlay:

// SCSS
@mixin overlay() {
  color: lightslategrey;
  font-size: 10px;
  letter-spacing: 0.1em;
  line-height: 12px;
  text-transform: uppercase;
}
  
.modal-background {
  @include overlay();
}

.product-link {
  @include overlay();
}

.image-pattern {
  @include overlay();
}

// Генерируемый CSS
.modal-background {
  color: lightslategrey;
  font-size: 10px;
  letter-spacing: 0.1em;
  line-height: 12px;
  text-transform: uppercase;
}

.product-link {
  color: lightslategrey;
  font-size: 10px;
  letter-spacing: 0.1em;
  line-height: 12px;
  text-transform: uppercase;
}

.image-pattern {
  color: lightslategrey;
  font-size: 10px;
  letter-spacing: 0.1em;
  line-height: 12px;
  text-transform: uppercase;
}

Список свойств просто повторяется столько раз, сколько вызывается @include overlay().

Правило @extend является более эффективным, поскольку оно записывает общие свойства только один раз.

Заполнители

Итак, вы могли бы думать: «.small-uppercase не семантичен! Могу ли я использовать его в моём HTML?».

Вы правы, именно поэтому в Sass существуют заполнители.

Если вы не хотите или вам не нужен селектор .small-uppercase, превратите его в заполнитель Sass, заменив точку на символ процента (%):

// SCSS
%small-uppercase {
  color: lightslategrey;
  font-size: 10px;
  letter-spacing: 0.1em;
  line-height: 12px;
  text-transform: uppercase;
  }
  
.modal-background {
  @extend %small-uppercase;
}

.product-link {
  @extend %small-uppercase;
}

.image-pattern {
  @extend %small-uppercase;
}

// Генерируемый CSS
.modal-background,
.product-link,
.image-pattern {
  color: lightslategrey;
  font-size: 10px;
  letter-spacing: 0.1em;
  line-height: 12px;
  text-transform: uppercase;
}

Обратите внимание, что сгенерированный CSS не включает больше селектор .small-uppercase. Это потому, что правило %small-uppercase только предоставляет место для общих свойств.

Разница между расширением, заполнителем и примесью

  Описание Вызов Группирует селекторы? Допускает параметры?
Примеси @mixin name() @include name() Нет Да
Расширения Любой класс @extend .class Да Нет
Заполнители %placeholder @extend %placeholder Да Нет

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

Перейти к заданиям

Автор: Джереми Томас
Последнее изменение: 05.10.2022

См. также