Коротко — да: %‑плейсхолдеры — это обычные селекторы Sass, их можно объявлять в любом месте файла, в том числе вложенными в другие правила, внутри @media или внутри миксинa. Но важно понимать, что их «контекст» сохраняется и влияет на то, куда будут добавлены селекторы при @extend.
Главные моменты и подводные камни:
- Вложенность. Если вы объявите %placeholder внутри другого селектора, то при расширении этот внешний контекст будет сохранён — расширяющий селектор будет подставлен на место плейсхолдер‑селекта в том же контексте.
Пример:
.parent {
%base { color: red; }
}
.other { @extend %base; }
Скомпилируется примерно в:
.parent, .other { color: red; }
- @media / вложенные правила. Если плейсхолдер объявлен внутри @media, то расширения попадут в тот же медиаблок:
@media (min-width:600px) {
%mq-shared { font-size:16px; }
}
.box { @extend %mq-shared; }
-> правило для .box окажется внутри того же @media.
- Внутри миксина. Плейсхолдер, объявленный внутри миксина, «появится» в CSS только когда вы включите (include) этот миксин. Расширения будут привязаны к тому правилу, которое создаётся при включении. Если миксин не был включён ни разу, для расширения не будет «базы» и результат может быть неожиданным/ненужным.
Пример:
@mixin make-shared {
%shared { padding: 1rem; }
}
@include make-shared;
.x { @extend %shared; }
-> .x попадёт в то правило, которое создал make-shared.
- Порядок/область видимости. Sass разрешает @extend в целом по файлу — часто порядок объявлений не критичен — но если плейсхолдер создаётся только при включении миксина, то миксин должен быть включён где‑то в проекте, иначе расширять будет нечего.
Рекомендации:
- Для читаемости и предсказуемости обычно удобнее держать общие плейсхолдеры в одном месте (на верхнем уровне) и документировать их назначение.
- Если вы используете плейсхолдеры внутри @media или вложенных селекторов преднамеренно — это нормальная техника для создания контекстно‑ограниченных правил. Просто помните, что расширения будут «приписаны» к тому же контексту.
Если хотите, могу показать конкретный пример кода и то, как он скомпилируется в CSS.