본문 바로가기
1주차

<template> 태그와 Shadow DOM을 활용한 HTML 구성 분리

by mmhs 2025. 4. 11.

 

안녕하세요 WEB 파트 YB 문혜성입니다!

 

웹 개발을 하다 보면 같은 HTML 구조를 반복해서 복사하게 되는 경우가 많습니다.
카드 UI, 리스트, 모달… 처음엔 빠르게 개발되지만, 점점 코드가 길어지고 복잡해지면 수정할 때마다 실수가 생기고 유지보수도 힘들어지죠.

이럴 때 우리가 할 수 있는 건 HTML도 구성요소 단위로 분리해서 재사용하는 겁니다.
오늘 소개할 <template> 태그와 Shadow DOM은 바로 이런 문제를 해결해주는 기술이에요

프레임워크 없이도 HTML을 더 구조적으로, 모듈처럼 다룰 수 있는 방법은 무엇일까요?

지금부터 함께 살펴볼게요!


🔎 <template> 태그란?

 

✅ 무엇인가요?

 

<template> 태그는 HTML 내에 렌더링되지 않는 구조를 미리 정의해두는 용도입니다. 브라우저는 이 안의 내용을 처음엔 화면에 표시하지 않지만, JavaScript로 꺼내 사용할 수 있도록 저장해 둡니다.

 

✅ 왜 유용할까요?

  • 반복되는 UI 구조를 재사용할 수 있어 유지보수가 쉬워짐
  • 프레임워크 없이도 ‘컴포넌트’ 느낌의 코드 구조화 가능
  • 처음에는 렌더링되지 않기 때문에 초기 성능에도 부담 없음

 

🧪 실전 사용 예제: 카드 UI 반복 생성

 

그럼 실전 예제를 한번 알아볼까요?

아래는 템플릿을 복제해서 여러 개의 카드 UI를 만드는 예제입니다.

 

<template id="card-template">
  <div class="card">
    <h2 class="title"></h2>
    <p class="desc"></p>
  </div>
</template>

 

이 코드는 실제 페이지에는 보이지 않아요. 대신 자바스크립트를 통해 아래처럼 사용할 수 있습니다.

 

const data = [
  { title: "HTML 구성 분리", desc: "template 태그와 Shadow DOM을 함께 써보자!" },
  { title: "재사용 컴포넌트", desc: "HTML도 모듈화할 수 있다." }
];

const container = document.getElementById("container");
const template = document.getElementById("card-template");

data.forEach(item => {
  const clone = template.content.cloneNode(true);
  clone.querySelector(".title").textContent = item.title;
  clone.querySelector(".desc").textContent = item.desc;
  container.appendChild(clone);
});

 

✅ 여기서 중요한 포인트!

  • .content.cloneNode(true)를 통해 템플릿 안의 내용을 복사합니다.
  • 실제 DOM에 붙이기 전까지는 렌더링되지 않습니다.
  • id="card-template"로 특정 템플릿을 지정합니다.

🧊 Shadow DOM이란?

 

✅ 개념 정리

Shadow DOM은 HTML의 구조와 CSS 스타일을 캡슐화할 수 있는 기술입니다.
즉, 하나의 컴포넌트 내부에서 사용된 스타일이나 구조가 외부와 완전히 격리되죠.

이렇게 하면 어떤 일이 벌어질까요?

  • 외부 스타일이 컴포넌트 내부를 망치지 않음
  • 반대로, 컴포넌트 내부 스타일이 전역에 영향을 미치지도 않음

 

✅ 사용 예제

 

아래 예시는 사용자 카드 컴포넌트를 만드는 코드입니다.

class UserCard extends HTMLElement {
  constructor() {
    super();
    const shadow = this.attachShadow({ mode: "open" });

    shadow.innerHTML = `
      <style>
        .card { padding: 1rem; border: 1px solid #ccc; }
      </style>
      <div class="card">
        <h2>사용자 카드</h2>
        <p>Shadow DOM 내부 구조입니다</p>
      </div>
    `;
  }
}
customElements.define('user-card', UserCard);

 

 

✅ 정리하면?

 

  • attachShadow({ mode: "open" }): Shadow DOM을 붙이는 부분
  • 내부의 <style>은 바깥 CSS와 독립적으로 적용됨
  • customElements.define()을 통해 HTML 태그처럼 사용 가능

 


🧩 둘을 조합하면?

<template>과 Shadow DOM은 함께 사용하면 더욱 강력해집니다.

  • <template>: 컴포넌트 구조를 재사용할 수 있게 해줌
  • Shadow DOM: 컴포넌트의 내부 구조와 스타일을 외부로부터 보호

 

이 조합을 통해, 프레임워크 없이도 다음과 같은 결과를 얻을 수 있어요!

  • 유지보수 용이
  • 스타일 충돌 방지
  • 가볍고 빠른 구조 분리

 

✅ 언제 써야 할까?

 

 

 


💬 마무리하며

지금까지 HTML 구성 요소를 나누는 두 가지 방법을 살펴봤습니다.
템플릿은 구조 재사용을, Shadow DOM은 스타일 격리를 책임집니다.
React같은 프레임워크를 쓰지 않아도, Vanilla JS만으로도 강력한 UI 컴포넌트를 만들 수 있다는 점 기억해주세요!

프레임워크를 쓰기 전, 혹은 작고 빠른 기능을 만들고 싶을 때 이 방식으로 한번 시도해보는 건 어떨까요?

읽어주셔서 감사합니다!

 

 

 

 

출처: Shadow DOM: 궁극의 가이드, Exploring Shadow DOM for Web Development | Salesforce Trailhead, shadow DOM 사용 - 웹 API | 엠디엔