Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

@extend и заполнители

@extend говорит: «этот селектор должен получить все стили того». В отличие от миксина он не копирует объявления, а добавляет селектор в уже существующее правило. Селектор-заполнитель (placeholder), начинающийся с %, — правило только для расширения: сам по себе он в CSS не появляется.

Заполнитель

У нескольких видов сообщений общие базовые стили. Вынесите основу в заполнитель в styles/components/_alerts.scss:

// styles/components/_alerts.scss
%alert {
  padding: 12px 16px;
  border-radius: 8px;
}
 
.alert-success {
  @extend %alert;
  background: #dcfce7;
}
 
.alert-error {
  @extend %alert;
  background: #fee2e2;
}
// styles/main.scss
@use "components/alerts";
.alert-error, .alert-success {
  padding: 12px 16px;
  border-radius: 8px;
}
 
.alert-success {
  background: #dcfce7;
}
 
.alert-error {
  background: #fee2e2;
}
<style>
  .alert-error, .alert-success {
    padding: 12px 16px;
    border-radius: 8px;
  }
 
  .alert-success {
    background: #dcfce7;
  }
 
  .alert-error {
    background: #fee2e2;
  }
</style>
 
<p class="alert-success">Заказ оформлен.</p>
<p class="alert-error">Карта отклонена.</p>

Оба селектора добавлены в одно правило: базовые объявления встречаются в CSS только один раз. Самого %alert в результате нет.

Расширение класса

Расширять можно и обычный класс:

// styles/main.scss
.btn {
  padding: 8px 16px;
}
 
.btn-large {
  @extend .btn;
  font-size: 20px;
}
.btn, .btn-large {
  padding: 8px 16px;
}
 
.btn-large {
  font-size: 20px;
}

Теперь в HTML достаточно class="btn-large" — писать class="btn btn-large" не нужно.

Почему нужна осторожность

@extend меняет каждое правило, где встречается расширяемый селектор, а не только первое. Если .btn используется ещё в каком-то правиле, .btn-large добавится и туда:

// styles/main.scss
.btn {
  padding: 8px 16px;
}
 
.header .btn {
  color: white;
}
 
.btn-large {
  @extend .btn;
}
.btn, .btn-large {
  padding: 8px 16px;
}
 
.header .btn, .header .btn-large {
  color: white;
}

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

СитуацияЧто использовать
Общая основа внутри одного файла компонента@extend заполнителя %placeholder
Повторяемые стили с параметрамиМиксин
Стили, которые сочетаются в HTMLДва класса: btn btn-large

Расширяйте только заполнители, а не настоящие классы, и держите заполнитель в том же файле, что и правила, которые его расширяют.

Частая ошибка

@extend не может дотянуться из медиазапроса до селектора, объявленного снаружи:

// styles/main.scss
%hidden {
  display: none;
}
 
@media (max-width: 600px) {
  .sidebar {
    @extend %hidden;
  }
}

Sass остановится с ошибкой You may not @extend selectors across media queries. В таком случае используйте миксин: он копирует объявления внутрь медиазапроса, и это работает всегда.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.