Shadow DOM

컴포넌트 내부 DOM과 스타일에 독립된 경계를 만듭니다.

···
html
<div class="v"><header>STYLE BOUNDARY <span id="outerLabel">outer: blue</span></header><div class="stage shadow"><div class="outer" id="outer">document style<template id="tpl"><div class="inner">shadow card</div></template><div id="host"></div></div></div><div class="muted">outer selector stops at shadow root</div></div>
css
.v{width:min(94vw,760px);height:min(88vh,320px);padding:clamp(9px,2.4vmin,18px);border:1px solid var(--line);border-radius:12px;background:var(--surface);font:500 clamp(12px,2.4vmin,16px)/1.3 var(--font-sans,system-ui,sans-serif);display:flex;flex-direction:column;gap:clamp(5px,1.4vmin,10px);overflow:hidden}.v header{display:flex;align-items:center;justify-content:space-between;gap:8px;color:var(--accent);font-weight:700}.v header span{color:var(--muted);font-weight:500}.v .stage{flex:1;min-height:0;position:relative}.v .muted{color:var(--muted)}.v .active{background:color-mix(in srgb,var(--accent) 18%,var(--surface));border-color:var(--accent)!important;color:var(--fg)}.v button{font:inherit;color:var(--fg);background:var(--bg);border:1px solid var(--line);border-radius:7px;padding:5px 8px;cursor:pointer}.shadow{display:grid;place-items:center}.outer{width:70%;min-height:75%;padding:9px;border:2px dashed var(--accent-2);border-radius:9px;color:var(--accent-2);display:flex;align-items:center;justify-content:center;flex-direction:column;gap:7px;transition:color .5s,border-color .5s}.outer.hot{color:var(--accent-3);border-color:var(--accent-3)}#host{width:65%;display:block}
js
const host=document.getElementById("host");host.attachShadow({mode:"open"}).innerHTML="<style>.inner{padding:8px;text-align:center;color:white;background:#0e9f6e;border-radius:7px;font:600 13px system-ui}</style><div class=inner>shadow card</div>";let hot=false;function tick(){hot=!hot;document.getElementById("outer").classList.toggle("hot",hot);document.getElementById("outerLabel").textContent=hot?"outer: amber":"outer: blue"}tick();setInterval(tick,1100)

Shadow DOM은 호스트 요소 아래에 별도 트리를 붙입니다. 문서의 일반 선택자가 내부에 그대로 들어가지 않고, 컴포넌트 스타일도 바깥으로 새지 않습니다.

데모는 바깥 CSS 색을 바꿔도 내부 카드가 같은 색을 유지하는 모습을 보여줍니다. 공개 조정 지점이 필요하면 CSS 사용자 정의 속성이나 `::part`를 설계해야 합니다.

언제 쓰나

재사용 웹 컴포넌트의 스타일 충돌을 줄이고 내부 구조를 캡슐화할 때 씁니다.

페이지로 열기 ↗