@scope

선택자가 적용되는 범위를 DOM 경계로 묶어서, 하위 컴포넌트 CSS가 서로 새어 들어가지 않게 하는 규칙.

다른 이름: 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');

`.card p` 같은 자손 선택자는 "카드 안 어딘가의 p"를 전부 잡습니다. 카드 안에 또 다른 컴포넌트(예: 다른 카드, 위젯)가 중첩되면 이 선택자가 의도와 다르게 안쪽 컴포넌트까지 건드리는 일이 흔했고, 이걸 피하려고 CSS Modules나 styled-components 같은 스코핑 도구를 쓰는 게 일반적이었습니다.

`@scope (.card) to (.card__nested) { p { color: var(--accent) } }`은 스타일이 적용될 상한(`.card`)과 하한(`.card__nested`)을 CSS 안에서 직접 선언합니다. `to` 경계를 만나면 그 안쪽은 스코프에서 제외되는 "도넛 스코핑"이라, 중첩된 다른 컴포넌트를 자동으로 건드리지 않게 됩니다. `&`를 스코프 루트 참조로 쓸 수 있어 네이티브 CSS 네이팅과도 잘 맞습니다.

기본 지원은 caniuse/MDN baseline을 확인하세요. 미지원 브라우저에서는 CSS Modules·BEM 네이밍·shadow DOM 같은 빌드 타임 혹은 구조적 스코핑이 여전히 필요합니다.

언제 쓰나

카드 안에 카드처럼 같은 컴포넌트가 중첩될 때, 바깥 스타일이 안쪽까지 새는 걸 CSS만으로 막고 싶을 때.