Native CSS Nesting

CSS 네이팅

Native syntax for nesting selectors inside a parent rule without Sass — `&` refers to the parent.

Also known as: Nested CSS& selector
···
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="card">
    <div class="title">중첩 카드</div>
    <div class="body">호버해보세요 (2초마다 자동)</div>
  </div>
</div>
css
.wrap{position:relative;width:min(260px,92%)}
.card{
  padding:16px;border:1px solid var(--line);border-radius:12px;background:var(--surface);transition:background .3s,border-color .3s;
  .title{font-size:13px;font-weight:700;color:var(--fg)}
  .body{margin-top:4px;font-size:11px;color:var(--muted)}
  &.hover-sim{border-color:var(--accent);background:color-mix(in srgb, var(--accent) 8%, var(--surface))}
}
.card.fallback-hover{border-color:var(--accent);background:rgba(91,91,247,.08)}
.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 = CSS.supports('selector(&)');
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 ? '네이팅 지원됨' : '미지원 · flat CSS 폴백';
const card = document.getElementById('card');
const cls = ok ? 'hover-sim' : 'fallback-hover';
setInterval(() => card.classList.toggle(cls), 1800);

Repeating selectors that belong to the same component — `.card .title`, `.card:hover`, `.card .body` — is exactly what Sass/Less have solved for years. Projects sticking to plain CSS had no choice but to live with the repetition.

Native nesting lets you write rules inside rules: `.card { .title { ... } &:hover { ... } }`. `&` refers to the parent selector, and omitting a combinator implies a descendant selector automatically. Behavior isn't 100% identical to Sass nesting — specificity calculation for nested rules that don't start with `&` differs — so it's worth diffing the compiled CSS once when migrating.

Check caniuse/MDN baseline for support. Where it's missing, precompiling to flat CSS at build time with Sass/PostCSS remains the standard fallback.

When to use

Writing component-scoped CSS concisely without a preprocessor, or removing a build step.