본문으로 바로가기

TL;DR shadow DOM

category software engineering/frontend 2023. 4. 15. 23:59
728x90

개요

웹 컴포넌트의 중요한 측면은 캡슐화입니다. 캡슐화를 통해 마크업 구조, 스타일, 동작을 숨기고 페이지의 다른 코드로부터의 분리하여 각기 다른 부분들이 충돌하지 않게 하고, 코드가 깔끔하게 유지될 수 있게 합니다. Shadow DOM API는 캡슐화의 핵심 파트이며, 숨겨진 분리된 DOM을 요소에 부착하는 방법을 제공합니다.

caniuse

 

핵심

Shadow DOM은 숨겨진 DOM 트리가 통상적인 DOM 트리에 속한 요소에 부착될 수 있게 합니다. 이 shadow DOM 트리는 shadow root로부터 시작되어 원하는 모든 요소의 안에 부착될 수 있으며, 그 방법은 일반 DOM과 같습니다.

알아야 할 shadow DOM 용어가 있습니다.

  • Shadow host: shadow DOM이 부착되는 통상적인 DOM 노드.
  • Shadow tree: shadow DOM 내부의 DOM 트리.
  • Shadow boundary: shadow DOM이 끝나고, 통상적인 DOM이 시작되는 장소.
  • Shadow root: shadow 트리의 root 노드.

shadow DOM 내부의 코드 중 아무 것도 shadow DOM 외부의 모든 것에 영향을 주지 않는다는 점인데, 이는 편리한 캡슐화를 가능케 합니다.

 

기본 사용법

Element.attachShadow() 메서드를 사용하여 어떠한 요소에든 shadow root을 부착할 수 있습니다. 이 메서드는 매개변수로 하나의 옵션을 포함하는 옵션 객체를 취합니다. 그 옵션이란 mode 이며, open 혹은 closed 의 값을 가집니다.

let shadow = elementRef.attachShadow({mode: 'open'});
let shadow = elementRef.attachShadow({mode: 'closed'});

open 은 메인 페이지 맥락에서 작성된 JavaScript를 사용하여 shadow DOM에 접근할 수 있음을 의미합니다. 만약 mode: closed 로 사용자 정의 요소에 shadow root을 부착했다면, 외부로부터 shadow DOM에 접근할 수 없을 것입니다. 

let myShadowDom = myCustomElem.shadowRoot;

 

예제

웹 컴포넌트의 캡슐화 = Shadow DOM 으로, 우선 HTMLElement 를 확장하여 웹 컴포넌트를 정의합니다.

class PopUpInfo extends HTMLElement {
  constructor() {
    // 항상 super를 생성자에서 먼저 호출합니다
    super();

    // 요소 기능을 여기 작성합니다

    ...
  }
}

 

shadow root 생성하기

let shadow = this.attachShadow({mode: 'open'});

 

shadow DOM 구조 생성하기

// span들을 생성합니다
let wrapper = document.createElement('span');
wrapper.setAttribute('class', 'wrapper');

 

shadow DOM 스타일링

// shadow DOM에 적용할 몇 가지 CSS를 생성합니다
let style = document.createElement('style');

style.textContent = `
.wrapper {
  position: relative;
}

 

shadow DOM 을 Shadow Root 에 부착하기

// 생성된 요소들을 shadow dom에 부착합니다
shadow.appendChild(style);
shadow.appendChild(wrapper);

 

사용하기

// 새로운 요소를 정의합니다
customElements.define('popup-info', PopUpInfo);
<popup-info img="img/alt.png" data-text="Your card validation code (CVC) is an extra
                                    security feature — it is the last 3 or 4
                                    numbers on the back of your card.">
// 외부 스타일을 shadow dom에 적용합니다
const linkElem = document.createElement('link');
linkElem.setAttribute('rel', 'stylesheet');
linkElem.setAttribute('href', 'style.css');

// 생성된 요소를 shadow dom에 적용합니다
shadow.appendChild(linkElem);

<link> 요소는 shadow root의 페인트를 막지 않아, 스타일시트가 로딩되는 동안 스타일되지 않은 내용의 번쩍임 (FOUC, flash of unstyled content) 이 있을 수 있다는 것에 주의하세요.

 

대표 예제

input type="range" 는 세 개의 div 를 이용한 shadow dom 으로 만들어졌습니다.

<input type="range">

 

 

 

https://developer.mozilla.org/ko/docs/Web/API/Web_components/Using_shadow_DOM

 

shadow DOM 사용하기 - Web API | MDN

웹 컴포넌트의 중요한 측면은 캡슐화입니다. 캡슐화를 통해 마크업 구조, 스타일, 동작을 숨기고 페이지의 다른 코드로부터의 분리하여 각기 다른 부분들이 충돌하지 않게 하고, 코드가 깔끔하

developer.mozilla.org

 

'software engineering > frontend' 카테고리의 다른 글

QueryClient 뭐 써볼까?  (0) 2023.09.21
React 18 매력적인 기능  (0) 2023.05.01
React Server Component (RSC)  (0) 2023.04.15
React - Use() Hook  (0) 2023.03.29
React- 어떤 상태 관리 라이브러리를 사용할까?  (0) 2023.03.27