μΉ μ»΄ν¬λνΈμ Shadow DOMμ νμ©νμ¬ μ€νμΌ κ²©λ¦¬, ν₯μλ CSS μν€ν μ², μ μ§ κ΄λ¦¬κ° μ©μ΄ν μΉ κ°λ°μ ꡬνν©λλ€.
μΉ μ»΄ν¬λνΈ Shadow DOM: μ€νμΌ κ²©λ¦¬ λ° CSS μν€ν μ²
μΉ μ»΄ν¬λνΈλ μΉ μ ν리μΌμ΄μ κ΅¬μΆ λ°©μμ νμ νκ³ μμ΅λλ€. μ¬μ¬μ© κ°λ₯νκ³ μΊ‘μνλ HTML μμλ₯Ό λ§λλ κ°λ ₯ν λ°©λ²μ μ 곡ν©λλ€. μΉ μ»΄ν¬λνΈμ ν΅μ¬μ Shadow DOMμ΄λ©°, μ΄λ μ€μν μ€νμΌ κ²©λ¦¬λ₯Ό μ 곡νκ³ μ μ§ κ΄λ¦¬κ° λ μ©μ΄ν CSS μν€ν μ²λ₯Ό μ΄μ§ν©λλ€. μ΄ κΈ°μ¬μμλ Shadow DOMμ μ₯μ , ν¨κ³Όμ μΈ μ¬μ© λ°©λ², μ΅μ μΉ κ°λ° λ°©μμ λ―ΈμΉλ μν₯ λ±μ μμΈν μ΄ν΄λ³΄κ² μ΅λλ€.
Shadow DOMμ΄λ 무μμ λκΉ?
Shadow DOMμ μΊ‘μνλ₯Ό μ 곡νλ μΉ μ»΄ν¬λνΈ κΈ°μ μ μ€μν λΆλΆμ λλ€. μΉ μ»΄ν¬λνΈ λ΄μ μ¨κ²¨μ§ ꡬνμ΄λΌκ³ μκ°νμμμ€. Shadow DOM λ΄μ λͺ¨λ HTML, CSS λλ JavaScriptλ μ μ λ¬Έμλ‘λΆν° 보νΈλ©λλ€. μ΄λ¬ν 격리λ μ§μ μΌλ‘ λ 립μ μ΄κ³ μ¬μ¬μ© κ°λ₯ν μ»΄ν¬λνΈλ₯Ό λ§λλ λ° ν΅μ¬μ λλ€.
λ³Έμ§μ μΌλ‘ Shadow DOMμ μ»΄ν¬λνΈκ° μ체μ μΌλ‘ 격리λ DOM νΈλ¦¬λ₯Ό κ°λλ‘ ν©λλ€. μ΄ νΈλ¦¬λ μ£Ό λ¬Έμμ DOM μλμ μμ§λ§ λ¬Έμμ λλ¨Έμ§ CSS κ·μΉμ΄λ JavaScript μ½λμ μ§μ μ‘μΈμ€νκ±°λ μν₯μ λ°μ§ μμ΅λλ€. μ¦, νμ΄μ§μ λ€λ₯Έ μ€νμΌκ³Ό μΆ©λν μΌλ € μμ΄ μ»΄ν¬λνΈ λ΄μμ "button" λλ "container"μ κ°μ μΌλ°μ μΈ CSS ν΄λμ€ μ΄λ¦μ μ¬μ©ν μ μμ΅λλ€.
μ£Όμ κ°λ :
- Shadow Host: Shadow DOMμ΄ μ°κ²°λ μΌλ° DOM λ Έλμ λλ€. μ΄λ μΉ μ»΄ν¬λνΈκ° λ λλ§λλ μμμ λλ€.
- Shadow Tree: Shadow Host λ΄λΆμ DOM νΈλ¦¬μ λλ€. μ¬κΈ°μλ μ»΄ν¬λνΈμ λ΄λΆ ꡬ쑰, μ€νμΌ λ° λ‘μ§μ΄ ν¬ν¨λ©λλ€.
- Shadow Boundary: Shadow DOMμ λ¬Έμμ λλ¨Έμ§ λΆλΆκ³Ό λΆλ¦¬νλ μ₯λ²½μ λλ€. μ€νμΌκ³Ό μ€ν¬λ¦½νΈλ λͺ μμ μΌλ‘ νμ©λμ§ μλ ν μ΄ κ²½κ³λ₯Ό λμ μ μμ΅λλ€.
- Slots: Shadow DOM λ΄μ μ리 νμμ μμλ‘, light DOM(Shadow DOM μΈλΆμ μΌλ° DOM)μ μ½ν μΈ λ₯Ό μ»΄ν¬λνΈμ ꡬ쑰μ μ½μ ν μ μμ΅λλ€.
Shadow DOMμ μ¬μ©νλ μ΄μ λ 무μμ λκΉ?
Shadow DOMμ νΉν ν¬κ³ 볡μ‘ν μΉ μ ν리μΌμ΄μ μμ μλΉν μ΄μ μ μ 곡ν©λλ€.
- μ€νμΌ κ²©λ¦¬: CSS μΆ©λμ λ°©μ§νκ³ μ£Όλ³ νκ²½μ κ΄κ³μμ΄ μ»΄ν¬λνΈ μ€νμΌμ΄ μΌκ΄λκ² μ μ§λλλ‘ ν©λλ€. μ΄λ μλ‘ λ€λ₯Έ μμ€μ μ»΄ν¬λνΈλ₯Ό ν΅ν©νκ±°λ λκ·λͺ¨ νμμ μμ ν λ νΉν μ€μν©λλ€.
- μΊ‘μν: μ»΄ν¬λνΈμ λ΄λΆ ꡬ쑰 λ° κ΅¬ν μΈλΆ μ 보λ₯Ό μ¨κ²¨ λͺ¨λμ±μ μ΄μ§νκ³ μΈλΆ μ½λλ‘λΆν°μ μ°λ°μ μΈ μ‘°μμ λ°©μ§ν©λλ€.
- μ½λ μ¬μ¬μ©μ±: μ€νμΌ μΆ©λμ λν λλ €μ μμ΄ λ€μν νλ‘μ νΈμ μ½κ² ν΅ν©ν μ μλ μ§μ μΌλ‘ λ 립μ μ΄κ³ μ¬μ¬μ© κ°λ₯ν μ»΄ν¬λνΈλ₯Ό λ§λ€ μ μμ΅λλ€. μ΄λ κ°λ°μ ν¨μ¨μ±μ ν₯μμν€κ³ μ½λ μ€λ³΅μ μ€μ λλ€.
- λ¨μνλ CSS μν€ν μ²: λ³΄λ€ μ»΄ν¬λνΈ κΈ°λ° CSS μν€ν μ²λ₯Ό μ₯λ €νμ¬ μ€νμΌ κ΄λ¦¬λ₯Ό λ³΄λ€ μ½κ² λ§λ€κ³ μ μ§ κ΄λ¦¬ν©λλ€. μ»΄ν¬λνΈ μ€νμΌ λ³κ²½μ μ ν리μΌμ΄μ μ λ€λ₯Έ λΆλΆμ μν₯μ λ―ΈμΉμ§ μμ΅λλ€.
- ν₯μλ μ±λ₯: κ²½μ°μ λ°λΌ Shadow DOMμ λ λλ§ λ³κ²½ μ¬νμ μ»΄ν¬λνΈμ λ΄λΆ κ΅¬μ‘°λ‘ κ²©λ¦¬νμ¬ μ±λ₯μ ν₯μμν¬ μ μμ΅λλ€. λΈλΌμ°μ λ Shadow DOM κ²½κ³ λ΄μμ λ λλ§μ μ΅μ νν μ μμ΅λλ€.
Shadow DOMμ λ§λλ λ°©λ²
JavaScriptλ₯Ό μ¬μ©νμ¬ Shadow DOMμ λ§λλ κ²μ λΉκ΅μ κ°λ¨ν©λλ€.
// μ μΉ μ»΄ν¬λνΈ ν΄λμ€ λ§λ€κΈ°
class MyComponent extends HTMLElement {
constructor() {
super();
// μμμ μλμ° DOM μ°κ²°
this.attachShadow({ mode: 'open' });
// μ»΄ν¬λνΈμ© ν
νλ¦Ώ λ§λ€κΈ°
const template = document.createElement('template');
template.innerHTML = `
λ΄ μ»΄ν¬λνΈμμ μλ
νμΈμ!
`;
// ν
νλ¦Ώμ 볡μ νμ¬ μλμ° DOMμ μΆκ°
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
}
// μ μμ μ μ
customElements.define('my-component', MyComponent);
μ€λͺ :
- `HTMLElement`μ νμ₯νλ μ ν΄λμ€λ₯Ό λ§λλλ€. μ΄κ²μ λͺ¨λ μ¬μ©μ μ μ μμμ κΈ°λ³Έ ν΄λμ€μ λλ€.
- μμ±μμμ `this.attachShadow({ mode: 'open' })`μ νΈμΆν©λλ€. μ΄κ²μ Shadow DOMμ λ§λ€κ³ μ»΄ν¬λνΈμ μ°κ²°ν©λλ€. `mode` μ΅μ μ `open` λλ `closed`κ° λ μ μμ΅λλ€. `open`μ Shadow DOMμ΄ μ»΄ν¬λνΈ μΈλΆμ JavaScriptμμ μ‘μΈμ€ν μ μμμ μλ―Έν©λλ€(μ: `element.shadowRoot` μ¬μ©). `closed`λ μ‘μΈμ€ν μ μμμ μλ―Έν©λλ€. μΌλ°μ μΌλ‘ λ ν° μ μ°μ±μ μν΄ `open`μ΄ μ νΈλ©λλ€.
- ν νλ¦Ώ μμλ₯Ό λ§λ€μ΄ μ»΄ν¬λνΈμ ꡬ쑰μ μ€νμΌμ μ μν©λλ€. μ΄λ μΈλΌμΈ HTMLμ νΌνκΈ° μν μΉ μ»΄ν¬λνΈμ νμ€ μ¬λ‘μ λλ€.
- ν νλ¦Ώμ μ½ν μΈ λ₯Ό 볡μ νκ³ `this.shadowRoot.appendChild()`λ₯Ό μ¬μ©νμ¬ Shadow DOMμ μΆκ°ν©λλ€. `this.shadowRoot`λ Shadow DOMμ 루νΈλ₯Ό λνλ λλ€.
- `
` μμλ light DOM(μΌλ° HTML)μμ μ»΄ν¬λνΈλ‘ μ λ¬λλ μ½ν μΈ μ μ리 νμμ μν μ ν©λλ€. - λ§μ§λ§μΌλ‘ `customElements.define()`μ μ¬μ©νμ¬ μ¬μ©μ μ μ μμλ₯Ό μ μν©λλ€. μ΄κ²μ μ»΄ν¬λνΈλ₯Ό λΈλΌμ°μ μ λ±λ‘ν©λλ€.
HTML μ¬μ©λ²:
μ΄κ²μ light DOMμ μ½ν
μΈ μ
λλ€.
"μ΄κ²μ light DOMμ μ½ν
μΈ μ
λλ€."λΌλ ν
μ€νΈκ° Shadow DOM λ΄μ `
Shadow DOM λͺ¨λ: Open vs. Closed
μμ μΈκΈνλ―μ΄ `attachShadow()` λ©μλλ `mode` μ΅μ μ νμ©ν©λλ€. λ κ°μ§ κ°λ₯ν κ°μ΄ μμ΅λλ€.
- `open`: μ»΄ν¬λνΈ μΈλΆμ JavaScriptκ° μμμ `shadowRoot` μμ±μ μ¬μ©νμ¬ Shadow DOMμ μ‘μΈμ€ν μ μλλ‘ νμ©ν©λλ€(μ: `document.querySelector('my-component').shadowRoot`).
- `closed`: μΈλΆ JavaScriptκ° Shadow DOMμ μ‘μΈμ€νμ§ λͺ»νλλ‘ ν©λλ€. `shadowRoot` μμ±μ `null`μ λ°νν©λλ€.
`open`κ³Ό `closed` κ°μ μ νμ νμν μΊ‘μν μμ€μ λ°λΌ λ€λ¦ λλ€. μΈλΆ μ½λκ° μ»΄ν¬λνΈμ λ΄λΆ ꡬ쑰 λλ μ€νμΌκ³Ό μνΈ μμ©νλλ‘ νμ©ν΄μΌ νλ κ²½μ°(μ: ν μ€νΈ λλ μ¬μ©μ μ μμ κ²½μ°) `open`μ μ¬μ©ν©λλ€. μΊ‘μνλ₯Ό μ격νκ² μ μ©νκ³ μΈλΆ μ‘μΈμ€λ₯Ό λ°©μ§νλ €λ©΄ `closed`λ₯Ό μ¬μ©ν©λλ€. κ·Έλ¬λ `closed`λ₯Ό μ¬μ©νλ©΄ λλ²κΉ λ° ν μ€νΈκ° λ μ΄λ €μμ§ μ μμ΅λλ€. `closed`λ₯Ό μ¬μ©ν΄μΌ νλ λ§€μ° κ΅¬μ²΄μ μΈ μ΄μ κ° μλ ν μΌλ°μ μΌλ‘ `open` λͺ¨λλ₯Ό μ¬μ©νλ κ²μ΄ κ°μ₯ μ’μ΅λλ€.
Shadow DOM λ΄μμ μ€νμΌ μ§μ
Shadow DOM λ΄μμ μ€νμΌμ μ§μ νλ κ²μ 격리 κΈ°λ₯μ ν΅μ¬ μΈ‘λ©΄μ λλ€. μμ μμμμ κ°μ΄ `
μ΄ μμμ `--button-color` λ° `--button-text-color` μ¬μ©μ μ μ μμ±μ light DOMμ `my-component` μμμ μ μλ©λλ€. κ·Έλ° λ€μ μ΄λ¬ν μμ±μ Shadow DOM λ΄μμ λ²νΌμ μ€νμΌμ μ§μ νλ λ° μ¬μ©λ©λλ€. μ¬μ©μ μ μ μμ±μ΄ μ μλμ§ μμ κ²½μ° κΈ°λ³Έκ°(`#007bff` λ° `#fff`)μ΄ μ¬μ©λ©λλ€.
CSS μ¬μ©μ μ μ μμ±μ Shadow Partsλ³΄λ€ μ»΄ν¬λνΈλ₯Ό μ¬μ©μ μ μνλ λ° λ μ μ°νκ³ κ°λ ₯ν λ°©λ²μ λλ€. μ΄λ₯Ό ν΅ν΄ μμμ μ€νμΌ μ§μ μ 보λ₯Ό μ»΄ν¬λνΈλ‘ μ λ¬νκ³ μ»΄ν¬λνΈ λͺ¨μμ λ€μν μΈ‘λ©΄μ μ μ΄νλ λ° μ¬μ©ν μ μμ΅λλ€. μ΄λ λ€μν λμμΈ μμ€ν μ μ½κ² μ μν μ μλ ν λ§ μ§μ κ°λ₯ν μ»΄ν¬λνΈλ₯Ό λ§λλ λ° νΉν μ μ©ν©λλ€.
κΈ°λ³Έ μ€νμΌ μ§μ μ λμ΄: Shadow DOMμ μ¬μ©ν κ³ κΈ CSS κΈ°μ
Shadow DOMμ κΈ°λ₯μ κΈ°λ³Έ μ€νμΌ μ§μ μ λμ΄ νμ₯λ©λλ€. CSS μν€ν μ² λ° μ»΄ν¬λνΈ μ€κ³λ₯Ό ν₯μμν¬ μ μλ λͺ κ°μ§ κ³ κΈ κΈ°μ μ μ΄ν΄λ³΄κ² μ΅λλ€.
CSS μμ
CSS μμμ μ€νμΌμ΄ Shadow DOM λ΄λΆ λ° μΈλΆλ‘ κ³λ¨μμΌλ‘ μ μ©λλ λ°©μμμ μ€μν μν μ ν©λλ€. `color`, `font` λ° `text-align`κ³Ό κ°μ νΉμ CSS μμ±μ κΈ°λ³Έμ μΌλ‘ μμλ©λλ€. μ¦, νΈμ€νΈ μμ(Shadow DOM μΈλΆ)μμ μ΄λ¬ν μμ±μ μ€μ νλ©΄ Shadow DOM λ΄μ μ€νμΌλ‘ λͺ μμ μΌλ‘ μ¬μ μλμ§ μλ ν Shadow DOM λ΄μ μμμμ μμλ©λλ€.
λ€μ μλ₯Ό κ³ λ €νμμμ€.
/* Shadow DOM μΈλΆμ μ€νμΌ */
my-component {
color: green;
font-family: Arial, sans-serif;
}
/* Shadow DOM λ΄λΆ */
μ΄ λ¨λ½μ νΈμ€νΈ μμμμ μμκ³Ό κΈκΌ΄ ν¨λ°λ¦¬λ₯Ό μμν©λλ€.
μ΄ κ²½μ° Shadow DOM λ΄μ λ¨λ½μ light DOMμ `my-component` μμμμ `color` λ° `font-family`λ₯Ό μμν©λλ€. μ΄λ μ»΄ν¬λνΈμ λν κΈ°λ³Έ μ€νμΌμ μ€μ νλ λ° μ μ©ν μ μμ§λ§ μμ λ° μ»΄ν¬λνΈ λͺ¨μμ λ―ΈμΉλ μν₯μ μΈμνλ κ²μ΄ μ€μν©λλ€.
:host μμ¬ ν΄λμ€
`:host` μμ¬ ν΄λμ€λ₯Ό μ¬μ©νλ©΄ Shadow DOM λ΄μμ νΈμ€νΈ μμ(light DOMμ μμ)λ₯Ό λμμΌλ‘ μ§μ ν μ μμ΅λλ€. μ΄λ ν΄λΉ μν λλ μμ±μ κΈ°λ°μΌλ‘ νΈμ€νΈ μμμ μ€νμΌμ μ μ©νλ λ° μ μ©ν©λλ€.
μλ₯Ό λ€μ΄ νΈμ€νΈ μμλ₯Ό λ§μ°μ€λ‘ κ°λ¦¬ν¬ λ λ°°κ²½μμ λ³κ²½ν μ μμ΅λλ€.
/* Shadow DOM λ΄λΆ */
μ΄λ κ² νλ©΄ μ¬μ©μκ° λ§μ°μ€λ₯Ό κ°λ¦¬ν¬ λ `my-component` μμμ λ°°κ²½μμ΄ νλμμΌλ‘ λ³κ²½λ©λλ€. `theme` μμ±μ΄ "dark"λ‘ μ€μ λ κ²½μ° `:host`λ₯Ό μ¬μ©νμ¬ ν΄λΉ μμ±μ κΈ°λ°μΌλ‘ νΈμ€νΈ μμλ₯Ό λμμΌλ‘ μ§μ ν μλ μμ΅λλ€.
/* Shadow DOM λ΄λΆ */
μ΄λ κ² νλ©΄ `theme` μμ±μ΄ "dark"λ‘ μ€μ λ κ²½μ° `my-component` μμμ μ΄λμ΄ ν λ§κ° μ μ©λ©λλ€.
:host-context μμ¬ ν΄λμ€
`:host-context` μμ¬ ν΄λμ€λ₯Ό μ¬μ©νλ©΄ μ¬μ©λλ 컨ν μ€νΈλ₯Ό κΈ°λ°μΌλ‘ νΈμ€νΈ μμλ₯Ό λμμΌλ‘ μ§μ ν μ μμ΅λλ€. μ΄λ λ€μν νκ²½μ΄λ ν λ§μ λ§κ² μ‘°μ λλ μ»΄ν¬λνΈλ₯Ό λ§λλ λ° μ μ©ν©λλ€.
μλ₯Ό λ€μ΄ νΉμ 컨ν μ΄λ λ΄μμ μ¬μ©λ λ μ»΄ν¬λνΈ λͺ¨μμ λ³κ²½ν μ μμ΅λλ€.
/* Shadow DOM λ΄λΆ */
μ΄λ κ² νλ©΄ ν΄λμ€ `dark-theme`μ΄ μλ μμ λ΄μμ μ¬μ©λ λ `my-component` μμμ μ΄λμ΄ ν λ§κ° μ μ©λ©λλ€. `:host-context` μμ¬ ν΄λμ€λ κΈ°μ‘΄ λμμΈ μμ€ν κ³Ό μννκ² ν΅ν©λλ μ»΄ν¬λνΈλ₯Ό λ§λλ λ° νΉν μ μ©ν©λλ€.
Shadow DOM λ° JavaScript
Shadow DOMμ μ£Όλ‘ μ€νμΌ κ²©λ¦¬μ μ€μ μ λμ§λ§ JavaScript μνΈ μμ©μλ μν₯μ λ―ΈμΉ©λλ€. λ°©λ²μ λ€μκ³Ό κ°μ΅λλ€.
μ΄λ²€νΈ μ¬μ§μ
Shadow DOM λ΄μμ μμλ μ΄λ²€νΈλ νΈμ€νΈ μμλ‘ μ¬μ§μ λ©λλ€. μ¦, Shadow DOM λ΄μμ μ΄λ²€νΈκ° λ°μνλ©΄ Shadow DOM μΈλΆμ μ΄λ²€νΈ μμ κΈ°μ λ³΄κ³ λλ μ΄λ²€νΈ λμμ μ€μ λ‘ μ΄λ²€νΈλ₯Ό νΈλ¦¬κ±°ν Shadow DOM λ΄μ μμκ° μλ νΈμ€νΈ μμκ° λ©λλ€.
μ΄κ²μ μΊ‘μν λͺ©μ μΌλ‘ μνλ©λλ€. μΈλΆ μ½λκ° μ»΄ν¬λνΈμ λ΄λΆ μμμ μ§μ μ‘μΈμ€νκ³ μ‘°μνλ κ²μ λ°©μ§ν©λλ€. κ·Έλ¬λ μ΄λ²€νΈλ₯Ό νΈλ¦¬κ±°ν μ νν μμλ₯Ό νμΈνκΈ°κ° λ μ΄λ €μμ§ μλ μμ΅λλ€.
μλ μ΄λ²€νΈ λμμ μ‘μΈμ€ν΄μΌ νλ κ²½μ° `event.composedPath()` λ©μλλ₯Ό μ¬μ©ν μ μμ΅λλ€. μ΄ λ©μλλ μλ λμμμ μμνμ¬ μ°½μμ λλλ μ΄λ²€νΈκ° ν΅κ³Όν λ Έλ λ°°μ΄μ λ°νν©λλ€. μ΄ λ°°μ΄μ κ²μ¬νμ¬ μ΄λ²€νΈλ₯Ό νΈλ¦¬κ±°ν μ νν μμλ₯Ό νμΈν μ μμ΅λλ€.
λ²μ μ§μ λ μ νκΈ°
JavaScriptλ₯Ό μ¬μ©νμ¬ Shadow DOMμ΄ μλ μ»΄ν¬λνΈ λ΄μμ μμλ₯Ό μ νν λ `shadowRoot` μμ±μ μ¬μ©νμ¬ Shadow DOMμ μ‘μΈμ€ν΄μΌ ν©λλ€. μλ₯Ό λ€μ΄ Shadow DOM λ΄μ λͺ¨λ λ¨λ½μ μ ννλ €λ©΄ λ€μ μ½λλ₯Ό μ¬μ©ν©λλ€.
const myComponent = document.querySelector('my-component');
const paragraphs = myComponent.shadowRoot.querySelectorAll('p');
μ΄λ κ² νλ©΄ νμ΄μ§μ λ€λ₯Έ κ³³μ μλ μμκ° μλ μ»΄ν¬λνΈμ Shadow DOM λ΄μμλ§ μμλ₯Ό μ νν μ μμ΅λλ€.
Shadow DOM μ¬μ©μ μν λͺ¨λ² μ¬λ‘
Shadow DOMμ μ΄μ μ ν¨κ³Όμ μΌλ‘ νμ©νλ €λ©΄ λ€μ λͺ¨λ² μ¬λ‘λ₯Ό κ³ λ €νμμμ€.
- κΈ°λ³Έμ μΌλ‘ Shadow DOM μ¬μ©: λλΆλΆμ μ»΄ν¬λνΈμμ μ€νμΌ κ²©λ¦¬ λ° μΊ‘μνλ₯Ό 보μ₯νλ €λ©΄ Shadow DOMμ μ¬μ©νλ κ²μ΄ μ’μ΅λλ€.
- μ¬λ°λ₯Έ λͺ¨λ μ ν: μΊ‘μν μꡬ μ¬νμ λ°λΌ `open` λλ `closed` λͺ¨λλ₯Ό μ νν©λλ€. μ격ν μΊ‘μνκ° νμνμ§ μμ κ²½μ° μΌλ°μ μΌλ‘ μ μ°μ±μ μν΄ `open`μ΄ μ νΈλ©λλ€.
- μ½ν μΈ νλ‘μ μ μ μν΄ μ¬λ‘― μ¬μ©: μ¬λ‘―μ νμ©νμ¬ λ€μν μ½ν μΈ μ λ§κ² μ‘°μ ν μ μλ μ μ°ν μ»΄ν¬λνΈλ₯Ό λ§λλλ€.
- Shadow Parts λ° μ¬μ©μ μ μ μμ±μ μ¬μ©νμ¬ μ¬μ©μ μ μ κ°λ₯ν λΆλΆ λ ΈμΆ: Shadow Parts λ° μ¬μ©μ μ μ μμ±μ μ¬μ©νμ¬ μΈλΆμμ μ μ΄λ μ€νμΌ μ§μ μ νμ©ν©λλ€.
- μ»΄ν¬λνΈ λ¬Έμν: λ€λ₯Έ κ°λ°μκ° μ»΄ν¬λνΈλ₯Ό λ μ½κ² μ¬μ©ν μ μλλ‘ μ¬μ© κ°λ₯ν μ¬λ‘―, Shadow Parts λ° μ¬μ©μ μ μ μμ±μ λͺ ννκ² λ¬Έμνν©λλ€.
- μ»΄ν¬λνΈ μ² μ ν ν μ€νΈ: μ»΄ν¬λνΈκ° μ¬λ°λ₯΄κ² μλνκ³ μ€νμΌμ΄ μ μ νκ² κ²©λ¦¬λμλμ§ νμΈνκΈ° μν΄ λ¨μ ν μ€νΈ λ° ν΅ν© ν μ€νΈλ₯Ό μμ±ν©λλ€.
- μ κ·Όμ± κ³ λ €: μ₯μ κ° μλ μ¬μ©μλ₯Ό ν¬ν¨νμ¬ λͺ¨λ μ¬μ©μκ° μ»΄ν¬λνΈμ μ‘μΈμ€ν μ μλμ§ νμΈν©λλ€. ARIA μμ± λ° μλ§¨ν± HTMLμ μ£Όμλ₯Ό κΈ°μΈμ΄μμμ€.
μΌλ°μ μΈ λ¬Έμ λ° ν΄κ²° λ°©λ²
Shadow DOMμ μλ§μ μ΄μ μ μ 곡νμ§λ§ λͺ κ°μ§ λ¬Έμ λ μ κΈ°ν©λλ€.
- λλ²κΉ : νΉν 볡μ‘ν λ μ΄μμ λ° μνΈ μμ©μ μ²λ¦¬ν λ Shadow DOM λ΄μμ μ€νμΌμ λλ²κΉ νλ κ²μ μ΄λ €μΈ μ μμ΅λλ€. λΈλΌμ°μ κ°λ°μ λꡬλ₯Ό μ¬μ©νμ¬ Shadow DOMμ κ²μ¬νκ³ μ€νμΌ μμμ μΆμ ν©λλ€.
- SEO: κ²μ μμ§ ν¬λ‘€λ¬λ Shadow DOM λ΄μ μ½ν μΈ μ μ‘μΈμ€νλ λ° μ΄λ €μμ κ²ͺμ μ μμ΅λλ€. μ€μν μ½ν μΈ κ° light DOMμμλ μ¬μ©ν μ μλμ§ νμΈνκ±°λ μλ² μΈ‘ λ λλ§μ μ¬μ©νμ¬ μ»΄ν¬λνΈ μ½ν μΈ λ₯Ό 미리 λ λλ§ν©λλ€.
- μ κ·Όμ±: μλͺ» ꡬνλ Shadow DOMμ μ κ·Όμ± λ¬Έμ λ₯Ό μΌμΌν¬ μ μμ΅λλ€. ARIA μμ± λ° μλ§¨ν± HTMLμ μ¬μ©νμ¬ λͺ¨λ μ¬μ©μκ° μ»΄ν¬λνΈμ μ‘μΈμ€ν μ μλμ§ νμΈν©λλ€.
- μ΄λ²€νΈ μ²λ¦¬: Shadow DOM λ΄μμ μ΄λ²€νΈ μ¬μ§μ μ λλλ‘ νΌλλ μ μμ΅λλ€. νμν κ²½μ° `event.composedPath()`λ₯Ό μ¬μ©νμ¬ μλ μ΄λ²€νΈ λμμ μ‘μΈμ€ν©λλ€.
μ€μ μ
Shadow DOMμ μ΅μ μΉ κ°λ°μμ κ΄λ²μνκ² μ¬μ©λ©λλ€. λͺ κ°μ§ μλ λ€μκ³Ό κ°μ΅λλ€.
- κΈ°λ³Έ HTML μμ: <video>, <audio> λ° <input type="range">μ κ°μ λ§μ κΈ°λ³Έ HTML μμλ λ΄λΆμ μΌλ‘ Shadow DOMμ μ¬μ©νμ¬ λ³΅μ‘ν UIλ₯Ό μΊ‘μνν©λλ€.
- UI λΌμ΄λΈλ¬λ¦¬ λ° νλ μμν¬: React, Angular λ° Vue.jsμ κ°μ μΈκΈ° μλ UI λΌμ΄λΈλ¬λ¦¬ λ° νλ μμν¬λ Shadow DOMμΌλ‘ μΉ μ»΄ν¬λνΈλ₯Ό λ§λλ λ©μ»€λμ¦μ μ 곡ν©λλ€.
- λμμΈ μμ€ν : λ§μ μ‘°μ§μμ Shadow DOMμΌλ‘ μΉ μ»΄ν¬λνΈλ₯Ό μ¬μ©νμ¬ λμμΈ μμ€ν μ μ¬μ¬μ© κ°λ₯ν μ»΄ν¬λνΈλ₯Ό ꡬμΆν©λλ€. μ΄λ κ² νλ©΄ μΉ μ ν리μΌμ΄μ μ 체μμ μΌκ΄μ±κ³Ό μ μ§ κ΄λ¦¬ ν¨μ¨μ±μ΄ 보μ₯λ©λλ€.
- νμ¬ μμ ―: μμ λ―Έλμ΄ λ²νΌ λ° κ΄κ³ λ°°λμ κ°μ νμ¬ μμ ―μ νΈμ€νΈ νμ΄μ§μμ μ€νμΌ μΆ©λμ λ°©μ§νκΈ° μν΄ Shadow DOMμ μ¬μ©νλ κ²½μ°κ° λ§μ΅λλ€.
μμ μλ리μ€: ν λ§κ° μ§μ λ λ²νΌ μ»΄ν¬λνΈ
μ¬λ¬ ν λ§(λ°μ, μ΄λμ λ° κ³ λλΉ)λ₯Ό μ§μν΄μΌ νλ λ²νΌ μ»΄ν¬λνΈλ₯Ό ꡬμΆνλ€κ³ κ°μ ν΄ λ³΄κ² μ΅λλ€. Shadow DOM λ° CSS μ¬μ©μ μ μ μμ±μ μ¬μ©νμ¬ μ¬μ©μ μ μ κ°λ₯νκ³ μ μ§ κ΄λ¦¬ κ°λ₯ν μ»΄ν¬λνΈλ₯Ό λ§λ€ μ μμ΅λλ€.
class ThemedButton extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
`;
}
}
customElements.define('themed-button', ThemedButton);
λ€λ₯Έ ν λ§λ‘ μ΄ μ»΄ν¬λνΈλ₯Ό μ¬μ©νλ €λ©΄ light DOMμμ CSS μ¬μ©μ μ μ μμ±μ μ μν μ μμ΅λλ€.
/* λ°μ ν
λ§ */
.light-theme themed-button {
--button-background-color: #f0f0f0;
--button-text-color: #333;
}
/* μ΄λμ΄ ν
λ§ */
.dark-theme themed-button {
--button-background-color: #333;
--button-text-color: #f0f0f0;
}
/* κ³ λλΉ ν
λ§ */
.high-contrast-theme themed-button {
--button-background-color: #000;
--button-text-color: #ff0;
}
κ·Έλ° λ€μ 컨ν μ΄λ μμμ μ μ ν ν΄λμ€λ₯Ό μΆκ°νμ¬ ν λ§λ₯Ό μ μ©ν μ μμ΅λλ€.
ν΄λ¦νμΈμ
ν΄λ¦νμΈμ
ν΄λ¦νμΈμ
μ΄ μμ μμλ Shadow DOM λ° CSS μ¬μ©μ μ μ μμ±μ μ¬μ©νμ¬ λ€μν ν λ§μ νκ²½μ μ½κ² μ μν μ μλ μ μ°νκ³ μ¬μ¬μ© κ°λ₯ν μ»΄ν¬λνΈλ₯Ό λ§λλ λ°©λ²μ λ³΄μ¬ μ€λλ€. λ²νΌμ λ΄λΆ μ€νμΌμ Shadow DOM λ΄μ μΊ‘μνλμ΄ νμ΄μ§μ λ€λ₯Έ μ€νμΌκ³Όμ μΆ©λμ λ°©μ§ν©λλ€. ν λ§ μ’ μ μ€νμΌμ CSS μ¬μ©μ μ μ μμ±μ μ¬μ©νμ¬ μ μλλ―λ‘ μ»¨ν μ΄λ μμμ ν΄λμ€λ₯Ό λ³κ²½νκΈ°λ§ νλ©΄ ν λ§λ₯Ό μ½κ² μ νν μ μμ΅λλ€.
Shadow DOMμ λ―Έλ
Shadow DOMμ μ΅μ μΉ κ°λ°μ κΈ°λ³Έ κΈ°μ μ΄λ©° κ·Έ μ€μμ±μ μμΌλ‘ λμ± μ»€μ§ κ²μ λλ€. μΉ μ ν리μΌμ΄μ μ΄ λμ± λ³΅μ‘ν΄μ§κ³ λͺ¨λνλ¨μ λ°λΌ μ€νμΌ κ²©λ¦¬ λ° μΊ‘μνμ νμμ±μ΄ λμ± μ€μν΄μ§ κ²μ λλ€. Shadow DOMμ μ΄λ¬ν λ¬Έμ μ λν κ°λ ₯νκ³ νμ€νλ μ루μ μ μ 곡νμ¬ κ°λ°μκ° μ μ§ κ΄λ¦¬ κ°λ₯νκ³ μ¬μ¬μ© κ°λ₯νλ©° νμ₯ κ°λ₯ν μΉ μ ν리μΌμ΄μ μ ꡬμΆν μ μλλ‘ μ§μν©λλ€.
Shadow DOMμ ν₯ν κ°λ°μλ λ€μμ΄ ν¬ν¨λ μ μμ΅λλ€.
- ν₯μλ μ±λ₯: Shadow DOMμ λ λλ§ μ±λ₯μ ν₯μμν€κΈ° μν μ§μμ μΈ μ΅μ ν.
- ν₯μλ μ κ·Όμ±: μ κ·Όμ± μ§μμ λν μΆκ° κ°μ μ¬νμΌλ‘, μ κ·Ό κ°λ₯ν μΉ μ»΄ν¬λνΈλ₯Ό λμ± μ½κ² ꡬμΆν μ μμ΅λλ€.
- λ κ°λ ₯ν μ€νμΌ μ§μ μ΅μ : Shadow DOMκ³Ό μννκ² ν΅ν©λμ΄ λμ± μ μ°νκ³ ννλ ₯μ΄ λ°μ΄λ μ€νμΌ μ§μ μ΅μ μ μ 곡νλ μλ‘μ΄ CSS κΈ°λ₯.
κ²°λ‘
Shadow DOMμ μΉ μ»΄ν¬λνΈμ μ€μν μ€νμΌ κ²©λ¦¬ λ° μΊ‘μνλ₯Ό μ 곡νλ κ°λ ₯ν κΈ°μ μ λλ€. κ·Έ μ΄μ κ³Ό ν¨κ³Όμ μΌλ‘ μ¬μ©νλ λ°©λ²μ μ΄ν΄νλ©΄ μ μ§ κ΄λ¦¬ κ°λ₯νκ³ μ¬μ¬μ© κ°λ₯νλ©° νμ₯ κ°λ₯ν μΉ μ ν리μΌμ΄μ μ λ§λ€ μ μμ΅λλ€. Shadow DOMμ κΈ°λ₯μ νμ©νμ¬ λμ± λͺ¨λνλκ³ κ°λ ₯ν μΉ κ°λ° μνκ³λ₯Ό ꡬμΆνμμμ€.
κ°λ¨ν λ²νΌμμ 볡μ‘ν UI μ»΄ν¬λνΈμ μ΄λ₯΄κΈ°κΉμ§ Shadow DOMμ μ€νμΌ κ΄λ¦¬ λ° κΈ°λ₯ μΊ‘μνλ₯Ό μν κ°λ ₯ν μ루μ μ μ 곡ν©λλ€. CSS μΆ©λμ λ°©μ§νκ³ μ½λ μ¬μ¬μ©μ±μ μ΄μ§νλ κΈ°λ₯μ μ΅μ μΉ κ°λ°μμκ² κ·μ€ν λꡬμ λλ€. μΉμ΄ κ³μ μ§νν¨μ λ°λΌ Shadow DOMμ λ§μ€ν°νλ κ²μ λ€μνκ³ λμμμ΄ λ³ννλ λμ§νΈ νκ²½μμ λ²μ±ν μ μλ κ³ νμ§, μ μ§ κ΄λ¦¬ κ°λ₯νκ³ νμ₯ κ°λ₯ν μΉ μ ν리μΌμ΄μ μ ꡬμΆνλ λ° μ μ λ μ€μν΄μ§ κ²μ λλ€. μ μΈκ³μ μΌλ‘ ν¬κ΄μ μΈ μ¬μ©μ κ²½νμ 보μ₯νκΈ° μν΄ λͺ¨λ μΉ μ»΄ν¬λνΈ λμμΈμμ μ κ·Όμ±μ κ³ λ €νλ κ²μ μμ§ λ§μμμ€.