Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

<template> / <slot>

『template』はブラウザに描画されない再利用可能なHTMLの雛形を定義する要素で、『slot』はWeb Componentsでカスタム要素の内側に外部からコンテンツを差し込む挿入口を定義するために使用します。

構文
<!-- template: 描画されないHTMLの雛形 -->
<template id="card-template">
  <div class="card">
    <h2 class="card-title"></h2>
    <p class="card-body"></p>
  </div>
</template>

<!-- slot: Web Componentsの挿入口(Shadow DOM内で使用) -->
<template id="my-card-template">
  <style>
    .card { border: 1px solid #ccc; padding: 16px; }
  </style>
  <div class="card">
    <!-- 名前なしスロット(デフォルトスロット) -->
    <slot></slot>
    <!-- 名前付きスロット -->
    <slot name="footer"></slot>
  </div>
</template>
属性・プロパティ一覧
属性 / プロパティ概要
template#contentテンプレート要素の内容にアクセスするためのプロパティです。『DocumentFragment』として取得できます。
cloneNode(true)テンプレートのコンテンツを複製するメソッドです。『true』を渡すと子要素も含めてディープコピーします。
slot(属性)カスタム要素の子要素に指定する属性で、どのスロットに挿入するかを名前で指定します。
slot nameShadow DOM内の『slot』要素に付ける名前です。対応するカスタム要素の子要素が差し込まれます。
サンプルコード
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <style>
    .card {
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 16px;
      margin: 8px;
      max-width: 300px;
    }
    .card-title { font-weight: bold; font-size: 1.1em; margin: 0 0 8px; }
    .card-body  { color: #555; margin: 0; }
  </style>
</head>
<body>

  <!-- template要素: ブラウザには描画されない -->
  <template id="card-template">
    <div class="card">
      <p class="card-title"></p>
      <p class="card-body"></p>
    </div>
  </template>

  <div id="container"></div>

  <script>
    // カードのデータ
    const cards = [
      { title: 'HTML',       body: 'Webページの構造を作る言語です。' },
      { title: 'CSS',        body: 'Webページのデザインを担当します。' },
      { title: 'JavaScript', body: 'Webページに動きを追加します。' },
    ];

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

    cards.forEach(({ title, body }) => {
      // テンプレートを複製してデータを書き込む
      const clone = template.content.cloneNode(true);
      clone.querySelector('.card-title').textContent = title;
      clone.querySelector('.card-body').textContent  = body;
      container.appendChild(clone);
    });
  </script>

</body>
</html>
実行結果

ページを開くとJavaScriptによってテンプレートが3回複製され、HTML・CSS・JavaScriptの3枚のカードが縦に並んで表示されます。テンプレートそのものはHTMLソースにあっても画面には表示されません。

<!-- 生成後のDOM(イメージ) -->
<div id="container">
  <div class="card">
    <p class="card-title">HTML</p>
    <p class="card-body">Webページの構造を作る言語です。</p>
  </div>
  <div class="card">
    <p class="card-title">CSS</p>
    <p class="card-body">Webページのデザインを担当します。</p>
  </div>
  <div class="card">
    <p class="card-title">JavaScript</p>
    <p class="card-body">Webページに動きを追加します。</p>
  </div>
</div>
概要

『template』要素は、ページ読み込み時にはブラウザに描画されず、CSSも適用されず、スクリプトも実行されないHTMLの「雛形」です。JavaScriptで複製(cloneNode)してDOMに追加することで初めて画面に表示されます。同じ構造を繰り返し生成する場合(リスト・カード・テーブル行など)に、innerHTML で文字列からHTMLを生成するよりも安全かつ効率的です。innerHTML にユーザー入力の文字列を渡すとXSSの危険がありますが、『template』を使ったcloneNode + textContentによる値の設定はXSSが発生しません。

『slot』はWeb Components(カスタム要素 + Shadow DOM)の仕組みの一部で、カスタム要素の利用者が外部から内容を差し込める「穴」を定義します。名前なしスロット(デフォルトスロット)はカスタム要素のすべての子要素を受け取り、『name』属性を付けた名前付きスロットは『slot="名前"』属性を持つ特定の子要素だけを受け取ります。

Web Componentsは独立したカプセル化されたUIコンポーネントをHTMLとJavaScriptで作成する仕様です。ReactやVueなどのフレームワークに依存しない、ブラウザネイティブのコンポーネント化の仕組みとして注目されています。ただし、Shadow DOMの仕様はやや複雑なため、まずは『template』要素によるシンプルなHTML雛形の活用から始めることをおすすめします。関連する要素として『script / noscript』も参照してください。

対応ブラウザ
Chrome Chrome
49 以降
25 以前 ×
Firefox Firefox
57 以降
21 以前 ×
Safari Safari
18 以降
7 以前 ×
Edge Edge
80 以降
12 以前 ×
IE IE
11 ×
全バージョンで非対応
Opera Opera
48 以降
14 以前 ×
iOS Safari iOS Safari
18 以降
7 以前 ×
Android Browser Android Browser
37 以降
4 以前 ×
Chrome Android Chrome Android
36 以降
25 以前 ×
Firefox Android Firefox Android
79 以降
21 以前 ×

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。