@scope

Bounds a set of selectors to a DOM subtree so nested components' CSS doesn't leak into or out of each other.

Also known as: CSS scopingDonut scoping
···
html
<div class="wrap">
  <div class="badge" id="badge"><svg viewBox="0 0 10 10"><path id="bpath" d="M1.5 5.2l2.6 2.6L8.5 2.4" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg><span id="btext">확인 중</span></div>
  <div class="card" id="outer">
    <p>바깥 카드 텍스트</p>
    <div class="card nested" id="inner"><p>중첩 카드 텍스트 (스코프 밖)</p></div>
  </div>
</div>
css
@scope (.card) to (.nested){ p{ color:var(--accent); font-weight:700 } }
.wrap{position:relative;width:min(260px,92%)}
.card{border:1px solid var(--line);border-radius:10px;padding:12px;background:var(--surface)}
.card p{font-size:11px;color:var(--muted)}
.nested{margin-top:8px}
.fallback-scope p{color:var(--accent);font-weight:700}
.fallback-scope .nested p{color:var(--muted);font-weight:400}
.badge{position:absolute;top:-30px;right:0;display:flex;align-items:center;gap:5px;padding:4px 9px;border-radius:999px;font-size:10px;font-weight:700;background:var(--bg);border:1px solid var(--line);color:var(--accent-3)}
.badge.no{color:var(--accent-2)}
.badge svg{width:9px;height:9px}
js
const ok = typeof CSSScopeRule !== 'undefined';
const b=document.getElementById('badge'),p=document.getElementById('bpath'),t=document.getElementById('btext');
b.classList.toggle('no', !ok);
p.setAttribute('d', ok ? 'M1.5 5.2l2.6 2.6L8.5 2.4' : 'M2 2l6 6M8 2l-6 6');
t.textContent = ok ? '@scope 지원됨' : '미지원 · 클래스 폴백';
if (!ok) document.getElementById('outer').classList.add('fallback-scope');

A descendant selector like `.card p` matches "any p inside a card." Nest another component inside that card — another card, a widget — and the selector often reaches further than intended, into the nested component. Avoiding that has meant reaching for scoping tools like CSS Modules or styled-components.

`@scope (.card) to (.card__nested) { p { color: var(--accent) } }` declares the upper (`.card`) and lower (`.card__nested`) bound directly in CSS. Anything past the `to` boundary is excluded — "donut scoping" — so a nested component isn't touched automatically. `&` can reference the scope root, pairing nicely with native CSS nesting.

Check caniuse/MDN baseline for support. Without it, build-time or structural scoping — CSS Modules, BEM naming, shadow DOM — remains necessary.

When to use

Nesting the same component inside itself — a card inside a card — and preventing outer styles from leaking in, using CSS alone.