【HTML Living Standard】template要素の使い方
template要素の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
templateオブジェクトは、初期状態ではブラウザに表示されないHTMLコンテンツを定義するためのオブジェクトです。この要素は、再利用可能なHTML構造を保持し、必要に応じてJavaScriptによってDOM(Document Object Model)に追加されることを目的としています。
template要素内のコンテンツは、ページがロードされてもブラウザによってレンダリングされず、ユーザーに表示されることもありません。また、その内部の要素は、初期状態ではスクリプトやCSSからも直接は参照されません。これにより、Webページに表示する準備ができていない、あるいは後で動的に生成する予定のコンテンツを一時的に安全に格納しておくことが可能になります。
template要素に格納されたコンテンツは、JavaScriptからcontentプロパティを通じてDocumentFragmentとしてアクセスできます。このDocumentFragmentは、JavaScriptの操作によって複製され、appendChild()などのメソッドを用いてDOMの任意の場所に挿入されることで、初めてユーザーに表示されるようになります。
この機能は、同じHTML構造を繰り返し利用する場合や、ユーザーの操作、非同期データ取得に応じて動的にコンテンツを生成する場合に非常に有用です。特に、Webコンポーネント(Custom Elements)の実装において、その構成要素となるHTMLスロットを定義するための標準的な方法として広く活用されています。templateを使用することで、Webアプリケーションのパフォーマンス向上とコードの整理に貢献できます。
構文(syntax)
1<template> 2 <!-- ここに、スクリプトによって後でクローンされ、DOMに挿入されるコンテンツを配置します。 --> 3 <p>テンプレート内のコンテンツ</p> 4 <button>ボタン</button> 5</template>
引数(parameters)
引数なし
引数はありません
戻り値(return)
戻り値なし
戻り値はありません
サンプルコード
HTML template 要素で動的にコンテンツを作成する
1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>HTML Template 要素の基本</title> 7 <style> 8 /* 見た目を分かりやすくするためのスタイル */ 9 .item { 10 border: 1px solid #ccc; 11 padding: 10px; 12 margin-bottom: 5px; 13 background-color: #f9f9f9; 14 } 15 .container { 16 margin-top: 20px; 17 border: 2px dashed #007bff; 18 padding: 15px; 19 } 20 </style> 21</head> 22<body> 23 <h1>HTML Template 要素の利用例</h1> 24 25 <p>以下の青い点線枠内に、テンプレートから動的に追加されたコンテンツが表示されます。</p> 26 27 <!-- テンプレート要素: この中身はページ読み込み時にはレンダリングされない --> 28 <template id="myTemplate"> 29 <div class="item"> 30 <h2>商品名: <span class="product-name"></span></h2> 31 <p>価格: <span class="product-price"></span>円</p> 32 <p>説明: これはテンプレートから生成された商品アイテムです。</p> 33 </div> 34 </template> 35 36 <!-- テンプレートから生成されたコンテンツが挿入される場所 --> 37 <div class="container" id="outputContainer"> 38 <h3>動的に追加された商品リスト</h3> 39 <!-- ここにテンプレートからクローンされた内容が追加されます --> 40 </div> 41 42 <script> 43 // テンプレート要素を取得 44 const template = document.getElementById('myTemplate'); 45 // コンテンツを挿入するコンテナ要素を取得 46 const outputContainer = document.getElementById('outputContainer'); 47 48 // 表示する商品データ 49 const products = [ 50 { name: 'ノートPC', price: 120000 }, 51 { name: 'スマートフォン', price: 85000 }, 52 { name: 'タブレット', price: 50000 } 53 ]; 54 55 // 各商品データを使ってテンプレートからコンテンツを生成し、ページに追加 56 products.forEach(product => { 57 // テンプレートの内容をディープコピー(子孫要素も含む) 58 const clone = template.content.cloneNode(true); 59 60 // クローンした要素内の特定の要素を更新 61 const productNameSpan = clone.querySelector('.product-name'); 62 const productPriceSpan = clone.querySelector('.product-price'); 63 64 if (productNameSpan) { 65 productNameSpan.textContent = product.name; 66 } 67 if (productPriceSpan) { 68 productPriceSpan.textContent = product.price.toLocaleString(); // 数字をローカル形式で表示 69 } 70 71 // 更新したクローンをコンテナに追加 72 outputContainer.appendChild(clone); 73 }); 74 </script> 75</body> 76</html>
HTMLの<template>要素は、ウェブページに直接表示されないが、JavaScriptと組み合わせて再利用可能なHTMLのひな形を定義するために使用されます。ページが読み込まれた時点では、<template>要素とその中身はブラウザによってレンダリングされず、ユーザーの目には見えません。そのため、隠れたコンテンツや、後から動的に追加するコンテンツの構造をあらかじめ用意しておくのに適しています。
サンプルコードでは、まず商品アイテムの構造を<template id="myTemplate">内に記述しています。この時点では画面には表示されません。次に、JavaScriptでこのテンプレート要素を取得し、template.contentプロパティを使ってテンプレートの中身にアクセスします。そして、cloneNode(true)メソッドにより、テンプレートの中身(子要素を含むすべて)を完全に複製しています。
複製したコンテンツに対して、商品名や価格といった具体的なデータをJavaScriptで埋め込み、最終的にウェブページの特定の場所(outputContainer)に<appendChild>メソッドで追加しています。これにより、同じ構造のコンテンツを複数回、効率的に生成し表示することができます。<template>要素自体には、直接の引数や戻り値といった概念は存在せず、その中身をJavaScriptで操作することが前提となります。
HTMLの<template>要素は、ページが読み込まれた時点では画面に表示されず、ブラウザによってレンダリングされない「非活性なコンテンツ」として扱われます。そのため、テンプレートの中身に直接スタイルを適用しても効果はありません。
この要素を利用する際は、必ずJavaScriptを使ってテンプレート要素のcontentプロパティから内容を取得し、cloneNode(true)メソッドで子孫要素を含めて複製してください。複製した要素にJavaScriptで必要なデータを埋め込み、その後、目的のDOM要素にappendChildなどで追加することで初めて画面に表示されます。これにより、繰り返し同じ構造の要素を効率的に生成でき、コードの可読性やメンテナンス性が向上します。外部から受け取ったデータをテンプレートに適用する際は、セキュリティ上のリスク(XSS攻撃など)を避けるため、textContentプロパティを使って安全に値を設定するよう注意してください。
HTML template 要素で動的にカードを生成する
1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>HTML Template サンプルコード</title> 7 <style> 8 /* 生成されるカードの基本的なスタイル */ 9 .item-card { 10 border: 1px solid #ddd; 11 border-radius: 8px; 12 padding: 15px; 13 margin: 10px; 14 width: 250px; 15 box-shadow: 0 4px 8px rgba(0,0,0,0.1); 16 background-color: #fff; 17 display: inline-block; /* カードを横並びに配置 */ 18 vertical-align: top; /* 上揃え */ 19 } 20 .item-card h3 { 21 color: #333; 22 margin-top: 0; 23 font-size: 1.2em; 24 } 25 .item-card p { 26 color: #666; 27 font-size: 0.9em; 28 } 29 #output-container { 30 margin-top: 20px; 31 padding-top: 10px; 32 border-top: 1px solid #eee; 33 } 34 button { 35 padding: 10px 20px; 36 font-size: 1em; 37 cursor: pointer; 38 background-color: #007bff; 39 color: white; 40 border: none; 41 border-radius: 5px; 42 margin-bottom: 20px; 43 } 44 button:hover { 45 background-color: #0056b3; 46 } 47 </style> 48</head> 49<body> 50 51 <h1>HTML `template` 要素の利用例</h1> 52 <p>「新しいカードを追加」ボタンをクリックすると、あらかじめ定義されたテンプレートから新しいコンテンツが動的に生成されます。</p> 53 54 <!-- 55 <template>要素は、ページがロードされたときにレンダリングされないHTMLコンテンツの断片を定義します。 56 主にJavaScriptを使って、その内容を複製(クローン)し、動的にDOMに追加するために使用されます。 57 これにより、再利用可能なUIコンポーネントを効率的に作成できます。 58 「free」というキーワードは、この要素が追加的なコストや複雑なJavaScriptコードなしに、 59 UIコンポーネントを再利用できる「手軽さ」や「自由な利用」を意味します。 60 --> 61 <template id="productCardTemplate"> 62 <div class="item-card"> 63 <h3>製品タイトル</h3> 64 <p>これはテンプレートから生成されたサンプルコンテンツです。</p> 65 <p>詳細はこちらをクリック!</p> 66 </div> 67 </template> 68 69 <button id="addCardButton">新しいカードを追加</button> 70 71 <!-- 生成されたカードがここに追加されます --> 72 <div id="output-container"> 73 <h2>生成されたコンテンツ:</h2> 74 </div> 75 76 <script> 77 // ボタン要素と、生成されたカードを追加するコンテナ要素を取得します。 78 const addButton = document.getElementById('addCardButton'); 79 const outputContainer = document.getElementById('output-container'); 80 81 // <template>要素を取得します。 82 const productTemplate = document.getElementById('productCardTemplate'); 83 84 let cardCount = 0; // 生成されたカードの数を追跡 85 86 // ボタンがクリックされたときのイベントリスナーを設定します。 87 addButton.addEventListener('click', () => { 88 cardCount++; 89 90 // テンプレートの内容を複製(クローン)します。 91 // cloneNode(true) は、テンプレート内の全ての子孫要素も深く複製することを意味します。 92 const clonedContent = productTemplate.content.cloneNode(true); 93 94 // 複製したコンテンツ内の特定の要素を更新することができます。 95 // ここでは、タイトルにカード番号を追加しています。 96 const titleElement = clonedContent.querySelector('h3'); 97 if (titleElement) { 98 titleElement.textContent = `製品タイトル #${cardCount}`; 99 } 100 101 // 複製したコンテンツを、指定されたコンテナ(outputContainer)に追加します。 102 // これにより、テンプレートの内容が実際にウェブページに表示されます。 103 outputContainer.appendChild(clonedContent); 104 }); 105 </script> 106 107</body> 108</html>
HTMLのtemplate要素は、ウェブページに直接表示されない、再利用可能なHTMLコンテンツのひな形を定義するための要素です。ページが読み込まれた時点では画面に表示されませんが、JavaScriptなどのスクリプトを使ってその内容を複製し、必要な時にウェブページへ動的に追加できます。これにより、同じ構造を持つUIコンポーネント(例えば、カードやリストアイテムなど)を効率的に繰り返し生成することが可能になります。
サンプルコードでは、<template id="productCardTemplate">内に製品カードの基本的なHTML構造が定義されています。このテンプレートは初期状態では画面に表示されませんが、「新しいカードを追加」ボタンがクリックされるたびに、JavaScriptがテンプレートの内容を複製し、タイトルなどの情報を動的に更新しながら、output-containerへ追加しています。
template要素自体には、特定の引数や戻り値はありません。これは、あくまでコンテンツの「入れ物」として機能し、その中身をスクリプトで操作することを前提としているためです。キーワードの「free」は、このtemplate要素が、追加的なコストや複雑なJavaScriptコードなしに、ウェブサイトに動的なコンテンツを簡単に追加し、UIコンポーネントを自由に再利用できるという利便性を意味しています。これにより、開発者は効率的にインタラクティブなウェブページを作成できます。
HTMLのtemplate要素は、ページが読み込まれた時点ではブラウザに表示されない「ひな形」です。表示するには、JavaScriptを使ってその内容を動的に複製し、既存のHTML要素に追加する必要があります。テンプレートの中身を取得する際は、要素自体ではなく.contentプロパティを使います。また、子要素も含めて完全に複製するにはcloneNode(true)と引数にtrueを指定することが非常に重要です。複製したコンテンツは、appendChild()などのメソッドで対象のDOM要素へ追加することで初めて画面に表示されます。複製後にテキストなどを変更する場合は、複製された内容に対して操作を行い、元のtemplate要素を直接変更しないようご注意ください。この要素は、手軽に再利用可能なUIコンポーネントを作成するのに役立ちます。