@scope лучше, чем Shadow DOM и «БЭМ-переусложнение»Когда речь заходит об изоляции стилей компонента, обычно вспоминают Shadow DOM или жёсткую методологию БЭМ. Но у обоих подходов есть боль: Shadow DOM — это тяжеловесная архитектура и потеря глобальных токенов, а БЭМ часто вырождается в «модификатор на модификаторе» и классы уровня
block__element--modifier--state.В 2023–2024 все стабильные браузеры приняли CSS
@scope. Он решает ровно ту задачу, ради которой раньше придумывали сложные обёртки.Синтаксис:
@scope (.card) {
:scope { border: 1px solid #d0d7de; }
.title { font-weight: 600; }
.button { padding: 8px 12px; }
}Вся магия: селекторы внутри
@scope применяются только к элементам внутри .card. При этом сами классы — обычные, без card__title, без завязки на структуру.Можно ограничить скоуп ещё точнее — до конкретной вложенности:
@scope (.media) to (.media__content) {
img { border-radius: 8px; }
}Здесь стили достаются только элементам между
.media и .media__content.Чем это удобно в реальном проекте:
- не нужен Shadow DOM ради изоляции одного карточного блока;
- не нужно на каждый чих придумывать новый БЭМ-элемент;
- CSS остаётся плоским и предсказуемым;
- можно аккуратно расширять стили библиотечного компонента без риска зацепить чужое.
Почему это не «ещё один препроцессор»:
@scope — нативная фича CSS. В отличие от вложенности в SCSS, он создаёт настоящую границу для каскада: селекторы из внешнего мира применяются к внутрям скоупа, но селекторы внутри скоупа не «утекают» наружу. Именно это ломало всю игру ещё вчера.БЭМ не отменяется полностью — но там, где раньше нужен был блок с корнем-обёрткой, теперь достаточно легкочитаемого
@scope. Компонент становится по-настоящему локальным без лишней разметки и без проклятия специфичности.Важный нюанс:
@scope управляет каскадом, но не специфичностью. Если снаружи написан селектор с #id или ультра-специфичный !important, он всё равно перебьёт скоуп — как и любое другое CSS-правило. Поэтому внутрь скоупа лучше не класть слишком сложные селекторы, а на верхнем уровне не злоупотреблять !important.Кроссбраузерность сегодня — зелёная: все современные Chrome, Firefox, Safari поддерживают
@scope без флагов.Куда копать дальше:
- CSS Scope Specification — https://drafts.csswg.org/css-cascade-6/
- MDN: @scope — https://developer.mozilla.org/en-US/docs/Web/CSS/@scope
Коротко: если вам нужна чистая локальность стилей «здесь и сейчас» — берите
@scope. Shadow DOM оставьте для настоящих web components, а БЭМ — для крупных переиспользуемых систем, где скоуп будет лишним уровнем.