캐스케이드 레이어

Cascade Layers

`@layer`로 스타일을 이름 붙인 층으로 나눠서, 선택자 특이도와 무관하게 층 순서로 우선순위를 정하는 기능.

다른 이름: @layer
···
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 id="chip" class="chip">낮은 특이도가 이깁니다</div>
</div>
css
@layer base, utilities;
@layer base{ #chip.a{ background:var(--accent-2); color:#fff } }
@layer utilities{ .chip{ background:var(--accent-3); color:#0a0a12 } }
.wrap{position:relative;width:100%;height:100%;display:grid;place-items:center}
.chip{padding:12px 18px;border-radius:10px;font-size:12px;font-weight:700;transition:background .3s,color .3s}
.chip.fallback{background:var(--accent-2)!important;color:#fff!important}
.badge{position:absolute;top:10px;right:10px;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);z-index:2}
.badge.no{color:var(--accent-2)}
.badge svg{width:9px;height:9px}
js
const ok = typeof CSSLayerBlockRule !== '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 ? '@layer 지원됨 — 나중 층 승리' : '미지원 · !important 폴백';
const chip = document.getElementById('chip');
chip.classList.add('a');
if (!ok) chip.classList.add('fallback');

리셋 CSS, 디자인 시스템, 컴포넌트, 유틸리티 클래스가 한 프로젝트에 섞이면 특이도 싸움이 벌어집니다. 유틸리티 클래스 `.text-red`가 컴포넌트의 `.card .title`을 이기게 하려고 `!important`를 붙이거나 선택자를 일부러 복잡하게 만드는 임시방편이 흔했습니다.

`@layer reset, base, components, utilities;`로 순서를 먼저 선언하면, 그 뒤로는 각 층 안의 선택자가 아무리 특이도가 낮아도 나중 층이 이전 층을 이깁니다 — 특이도 계산은 레이어 안에서만 일어나고, 레이어 간 우선순위는 오직 선언 순서로 정해집니다. Tailwind 같은 유틸리티 프레임워크도 내부적으로 레이어를 씁니다.

기본 지원은 caniuse/MDN baseline을 확인하세요. 미지원 브라우저에서는 지금까지처럼 CSS 파일을 로드 순서로 관리하고 특이도를 신중히 설계하는 것이 유일한 대안입니다.

언제 쓰나

리셋·디자인 시스템·유틸리티 클래스가 섞인 대규모 프로젝트에서 `!important` 없이 우선순위를 정할 때.