Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【HTML Living Standard】slot要素の使い方

slot要素の使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

slotオブジェクトは、Web Componentsのコンテキストにおいて、カスタム要素のシャドウDOM内部に外部からコンテンツを挿入するためのプレースホルダーを表すオブジェクトです。この要素を用いることで、カスタム要素を利用する側が提供するHTMLコンテンツを、カスタム要素の内部にある特定の場所で表示させることが可能になります。

slot要素の主な目的は、カスタム要素の再利用性と柔軟性を向上させることです。カスタム要素の内部構造に直接手を加えることなく、必要な部分にのみ動的にコンテンツを差し込めるようになります。

具体的な使用方法として、slot要素はカスタム要素のシャドウDOMテンプレート内に配置されます。カスタム要素を使用する側は、子要素に対してslot属性を指定することで、その子要素をシャドウDOM内の特定のslot要素(差し込み口)に割り当てることができます。

特に、name属性を持つslot要素は「名前付きスロット」と呼ばれ、特定の名前が一致するコンテンツのみを受け入れます。対照的に、name属性を持たないslot要素は「デフォルトスロット」として機能し、名前付きスロットに割り当てられなかったすべてのコンテンツを受け入れる役割を果たします。このように、slotはWeb Componentsにおいて、強力かつ柔軟なコンポーネントシステムを構築するための重要な機能です。

公式リファレンス: <slot>: The Web Component Slot element

構文(syntax)

1<slot name="スロット名"></slot>

引数(parameters)

引数なし

引数はありません

戻り値(return)

戻り値なし

戻り値はありません

サンプルコード

HTML slot要素でWeb Componentsを拡張する

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 slot要素の利用例</title>
7</head>
8<body>
9
10    <h1>HTML slot要素の利用例</h1>
11
12    <!--
13        slot要素は、Web Components (カスタム要素) と組み合わせて使用され、
14        再利用可能なコンポーネントの内部に、外部からコンテンツを挿入するための
15        プレースホルダー(差し込み口)として機能します。
16
17        これにより、コンポーネントの構造は固定しつつ、その表示内容を柔軟に変更できます。
18    -->
19
20    <script>
21        // HTMLElementを継承して、カスタム要素「MyCard」を定義します。
22        // このクラスが、HTML上で <my-card> タグとして振る舞います。
23        class MyCard extends HTMLElement {
24            constructor() {
25                super(); // 親クラス(HTMLElement)のコンストラクタを呼び出します。
26
27                // シャドウDOMを作成し、このコンポーネントの内部構造とスタイルをカプセル化します。
28                // 'open'モードでは、シャドウDOMの内部にJavaScriptからアクセスできます。
29                const shadowRoot = this.attachShadow({ mode: 'open' });
30
31                // コンポーネントの構造を定義するテンプレートです。
32                // この中にslot要素を配置して、外部からコンテンツを受け取る場所を指定します。
33                const template = document.createElement('template');
34                template.innerHTML = `
35                    <style>
36                        /* このスタイルはシャドウDOM内の要素にのみ適用され、外部からは影響を受けません */
37                        .card-container {
38                            border: 1px solid #ccc;
39                            border-radius: 8px;
40                            margin-bottom: 20px; /* 複数のカードが並んだときの間隔 */
41                            max-width: 350px;
42                            font-family: sans-serif;
43                            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
44                            display: block; /* カスタム要素自体をブロック要素として扱います */
45                        }
46                        .card-header {
47                            background-color: #f0f0f0;
48                            padding: 10px 15px;
49                            border-bottom: 1px solid #eee;
50                            font-weight: bold;
51                            color: #333;
52                        }
53                        .card-body {
54                            padding: 10px 15px;
55                            color: #555;
56                        }
57                        .card-footer {
58                            background-color: #f9f9f9;
59                            padding: 8px 15px;
60                            border-top: 1px solid #eee;
61                            font-size: 0.9em;
62                            color: #777;
63                            text-align: right;
64                        }
65                    </style>
66                    <div class="card-container">
67                        <div class="card-header">
68                            <!-- 名前付きスロット: 'header' という名前のslot属性を持つコンテンツがここに入ります。
69                                 何も渡されなかった場合は「デフォルトヘッダー」が表示されます。 -->
70                            <slot name="header">デフォルトヘッダー</slot>
71                        </div>
72                        <div class="card-body">
73                            <!-- デフォルトスロット (名前なしスロット):
74                                 slot属性が指定されていないコンテンツがここに入ります。
75                                 何も渡されなかった場合は「デフォルトボディコンテンツ」が表示されます。 -->
76                            <slot>デフォルトボディコンテンツ</slot>
77                        </div>
78                        <div class="card-footer">
79                            <!-- 名前付きスロット: 'footer' という名前のslot属性を持つコンテンツがここに入ります。
80                                 何も渡されなかった場合は「デフォルトフッター」が表示されます。 -->
81                            <slot name="footer">デフォルトフッター</slot>
82                        </div>
83                    </div>
84                `;
85
86                // テンプレートの内容をシャドウDOMにクローンして追加します。
87                // cloneNode(true) は、テンプレートの内容とその子孫もすべてクローンすることを意味します。
88                shadowRoot.appendChild(template.content.cloneNode(true));
89            }
90        }
91
92        // 'my-card'というタグ名を、上で定義したMyCardクラスに関連付けて登録します。
93        // これにより、HTMLドキュメント内で <my-card> タグがWebコンポーネントとして機能するようになります。
94        customElements.define('my-card', MyCard);
95    </script>
96
97    <h2>カスタム要素にコンテンツを挿入する例</h2>
98    <!--
99        <my-card> タグは、上で定義したカスタム要素です。
100        その子要素に slot="属性名" を指定することで、カスタム要素内部の
101        <slot name="属性名"> にコンテンツを挿入できます。
102        slot属性がない子要素は、名前なしの <slot> に挿入されます。
103    -->
104    <my-card>
105        <!-- このh2要素が、カスタム要素内の <slot name="header"> の位置に挿入されます。 -->
106        <h2 slot="header">イベントのお知らせ</h2>
107
108        <!-- これらのp要素はslot属性がないため、カスタム要素内のデフォルトスロット (<slot>) の位置に挿入されます。 -->
109        <p>来週開催されるWeb技術ワークショップへのご参加をお待ちしております!</p>
110        <p>最新のHTML、CSS、JavaScriptのテクニックを学びましょう。</p>
111
112        <!-- このdiv要素が、カスタム要素内の <slot name="footer"> の位置に挿入されます。 -->
113        <div slot="footer">
114            <span>開催日: 2023年11月10日</span>
115            <button>詳細を見る</button>
116        </div>
117    </my-card>
118
119    <h2>スロットにコンテンツを渡さない場合の例(デフォルトコンテンツの表示)</h2>
120    <!--
121        カスタム要素に子要素を渡さない場合、または特定のスロットにコンテンツを渡さない場合、
122        その <slot> タグ内に記述されたデフォルトコンテンツが表示されます。
123    -->
124    <my-card>
125        <!--
126            このmy-cardには子要素がありません。
127            そのため、カスタム要素のテンプレート内の各 <slot> タグに記述された
128            デフォルトコンテンツ(例:「デフォルトヘッダー」)が表示されます。
129        -->
130    </my-card>
131
132</body>
133</html>

HTMLのslot要素は、Web Components(カスタム要素)を構築する際に使用され、再利用可能なコンポーネントの内部に、外部からコンテンツを差し込むための「プレースホルダー」(差し込み口)として機能します。これにより、コンポーネントの基本的な構造は固定しつつ、表示内容を柔軟に変更できるようになります。

この要素は、主にカスタム要素のShadow DOM内で定義されます。slot要素を配置することで、カスタム要素を利用する側がその内部に特定のコンテンツ(例えば、見出し、本文、ボタンなど)を挿入できる領域を指定します。

slot要素には「名前付きスロット」と「デフォルトスロット」(名前なしスロット)の2種類があります。カスタム要素のテンプレート内で<slot name="ヘッダー"></slot>のようにname属性を指定すると「名前付きスロット」となり、カスタム要素を使う側は<h2 slot="ヘッダー"></h2>のようにslot属性で名前を指定してコンテンツを挿入します。name属性がない<slot></slot>は「デフォルトスロット」で、カスタム要素の子要素のうち、slot属性が指定されていないものが自動的に挿入されます。

もしスロットにコンテンツが何も渡されなかった場合、<slot>タグの内部に記述されたコンテンツが「デフォルトコンテンツ」として表示されます。

slot要素自体には、直接的な引数はなく、特定の値を返す戻り値もありません。その主な役割は、コンポーネントの構造内でコンテンツの配置場所を宣言することにあります。

slot要素は、Web Components(カスタム要素とシャドウDOM)と組み合わせて使用する、コンテンツの差し込み口を定義する要素です。単体では機能しませんのでご注意ください。カスタム要素のテンプレート内部に配置され、外部から挿入されるHTMLコンテンツを受け取るプレースホルダーとして機能します。

特に注意すべき点は、カスタム要素のテンプレート内で定義するslot要素がコンテンツの差し込み口そのものを指し、カスタム要素を呼び出す側で子要素に指定するslot属性が、その子要素がどの差し込み口に挿入されるかを指定する役割を持つことです。slot要素内に記述した内容は、外部からコンテンツが提供されない場合に表示される「デフォルトコンテンツ」として機能します。

この仕組みを理解することで、再利用可能なWebコンポーネントにおいて、コンポーネントの構造は固定しつつ、その表示内容を柔軟にカスタマイズすることが可能になります。シャドウDOMによるスタイルとマークアップのカプセル化と組み合わせることで、より独立した保守性の高い部品の構築に役立ちます。

HTML slot でカスタム要素にコンテンツを挿入する

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 slot のサンプル</title>
7</head>
8<body>
9
10    <!--
11        <my-card> というカスタム要素の定義と使用例です。
12        Web Components の Shadow DOM 内で <slot> 要素を使用し、
13        カスタム要素の内部に外部からコンテンツを挿入する方法を示します。
14    -->
15
16    <!--
17        <my-card> タグの内部に記述されたコンテンツ(h2, p, button)は、
18        カスタム要素の Shadow DOM 内の <slot> に挿入されます。
19    -->
20    <my-card>
21        <h2>これはカードのタイトルです</h2>
22        <p>slot要素は、カスタム要素の再利用性を高めるために、外部からコンテンツを動的に挿入するためのプレースホルダーとして機能します。</p>
23        <button>詳細を見る</button>
24    </my-card>
25
26    <my-card>
27        <h3>別のカード</h3>
28        <p>同じカスタム要素でも、異なるコンテンツを渡すことで、多様な表示が可能です。</p>
29    </my-card>
30
31    <script>
32        /**
33         * MyCard クラスは、HTMLElement を拡張してカスタム要素 <my-card> を定義します。
34         * その Shadow DOM 内で <slot> を使用して、外部からのコンテンツを受け入れます。
35         */
36        class MyCard extends HTMLElement {
37            constructor() {
38                super(); // HTMLElement のコンストラクタを呼び出す
39
40                // Shadow DOM を作成し、内部構造をカプセル化します。
41                // mode: 'open' は、JavaScript から Shadow DOM にアクセスできることを意味します。
42                const shadow = this.attachShadow({ mode: 'open' });
43
44                // カスタム要素の内部構造を定義するためのテンプレートを作成します。
45                const template = document.createElement('template');
46                template.innerHTML = `
47                    <style>
48                        /* Shadow DOM 内部の要素にのみ適用されるスタイルです */
49                        .card-container {
50                            border: 1px solid #ddd;
51                            padding: 15px;
52                            margin: 10px;
53                            border-radius: 8px;
54                            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
55                            background-color: #f9f9f9;
56                            max-width: 300px;
57                        }
58                    </style>
59                    <div class="card-container">
60                        <!--
61                            ここが <slot> 要素です。
62                            <my-card> タグの内部に記述されたコンテンツが、
63                            この <slot> の位置に挿入されます。
64                            (名前なしのデフォルトスロット)
65                        -->
66                        <slot></slot>
67                    </div>
68                `;
69
70                // テンプレートの内容を Shadow DOM に追加します。
71                // cloneNode(true) でテンプレートとそのすべての子孫をコピーします。
72                shadow.appendChild(template.content.cloneNode(true));
73            }
74        }
75
76        // 'my-card' というタグ名でカスタム要素を登録します。
77        // これにより、HTML 内で <my-card> タグが使用可能になります。
78        customElements.define('my-card', MyCard);
79    </script>
80
81</body>
82</html>

HTMLの<slot>要素は、Web Componentsと呼ばれる技術の一部として、カスタム要素内で外部からコンテンツを動的に挿入するためのプレースホルダーとして機能します。システムエンジニアを目指す方にとって、再利用性の高いコンポーネントを作成する上で非常に重要な要素です。

具体的には、<my-card>のような独自に定義したカスタム要素の内部構造(Shadow DOM)に<slot>を配置することで、そのカスタム要素タグの間に記述されたHTMLコンテンツを、<slot>が置かれた位置に表示させることができます。これにより、同じ見た目のカードコンポーネントでも、「タイトル」や「説明文」、「ボタン」といった中身のコンテンツを、カスタム要素を使用する側で自由に指定できるようになります。

提供されたサンプルコードでは、<my-card>要素の中に<h2><p><button>といった要素が記述されており、これらがMyCardクラスのShadow DOM内に定義された<slot>の位置に自動的に挿入され、表示されています。このように、<slot>は、コンポーネントの構造とコンテンツを分離し、柔軟なコンテンツの埋め込みを可能にすることで、カスタム要素の再利用性を大きく向上させます。

この<slot>要素には、特別な引数はなく、処理結果を直接返す戻り値もありません。Web Componentsにおけるコンテンツ配布のメカニズムとして機能します。

slot要素は、Web Componentsという技術を用いてカスタム要素を定義する際に、Shadow DOM内で使用する特別な要素です。これは、作成したカスタム要素の内部に、その要素を使う側(親要素)からコンテンツを動的に挿入するための「プレースホルダー」として機能します。

このslot要素を正しく利用するには、JavaScriptでHTMLElementを拡張し、attachShadowメソッドを使ってShadow DOMを構築する一連のWeb Componentsの知識が不可欠です。slotname属性がない場合、カスタム要素のタグ内に直接記述されたコンテンツが全てこのデフォルトスロットに挿入されます。これにより、カスタム要素の内部構造をカプセル化しつつ、柔軟なコンテンツ挿入でコンポーネントの再利用性を大幅に高めることができます。Shadow DOM内のスタイルは外部CSSの影響を受けにくい特性を持つため、意図しないスタイルの上書きを防ぎ、独立性を保てる点にもご留意ください。

関連コンテンツ

関連IT用語

関連プログラミング言語