@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. В таком случае используйте миксин: он копирует объявления внутрь медиазапроса, и это работает всегда.