<slot></slot>

更新日
仕様 HTML Living Standard
分類 フロー・コンテンツ / フレージング・コンテンツ
利用場所 フレージング・コンテンツが置ける場所
内容 トランスペアレント(親要素のコンテンツモデルを継承)

slot要素は、Shadow DOM内におけるスロット(データの挿入口)を表します。


<slot name="example"></slot>

属性
任意属性
name="" スロットの名前 文字列 スロットを識別するための名前

次の例では、template要素内でslot要素を使用しています。

この場合、slot要素name属性の値と、カスタム要素(<my-element>)内にあるslot属性の値を一致させることで、カスタム要素内で定義された値が特定のslot要素に挿入されるようになります。

<template id="my-template">

   <style>
   div {
      margin: 0 0 1.2em;
      border: 1px #c0c0c0 solid;
      font-weight: bold;
   }
   </style>

   <div>
      <slot name="sei"></slot>
      <slot name="mei"></slot>
   </div>

</template>


<my-element>
<span slot="sei">山田</span>
<span slot="mei">太郎</span>
</my-element>

<my-element>
<span slot="sei">鈴木</span>
<span slot="mei">花子</span>
</my-element>

<my-element>
<span slot="sei">佐藤</span>
</my-element>


<script>

   customElements.define('my-element',
      class extends HTMLElement {
         constructor() {
            super();
            var template = document.getElementById('my-template').content;
            var shadowRoot = this.attachShadow({mode: 'open'})
                             .appendChild(template.cloneNode(true));
         }
      }
   );

</script>

slot要素に挿入された値は、カスタム要素を配置した位置で次のように表示されます。(上記コードの実際の表示例です)

山田 太郎 鈴木 花子 佐藤

slot要素に値が挿入されなかった場合は、slot要素の内容が表示されることになります。

上記の例では、佐藤さんの下の名前が定義されていないため、slot要素内のテキスト()が表示されています。

  • template要素内で設定されたスタイルは、template要素内のHTMLにのみ適用されます。

name属性がない場合

name属性を持たない1つ目のslot要素には、シャドウホスト(下記の例では <my-element2>)の子要素のうちslot属性を持たない子要素がすべて挿入されます。

<template id="my-template2">

   <style>
   div {
      margin: 0 0 1.2em;
      border: 1px #c0c0c0 solid;
      font-weight: bold;
   }
   </style>

   <div>
      <p>段落1:<slot>既定のテキスト1</slot></p>
      <p>段落2:<slot>既定のテキスト2</slot></p>
   </div>

</template>


<my-element2>
<span>山田</span>
<span>太郎</span>
<span slot="demo1">鈴木</span>
<span slot="demo2">花子</span>
</my-element2>


<script>

   customElements.define('my-element2',
      class extends HTMLElement {
         constructor() {
            super();
            var template = document.getElementById('my-template2').content;
            var shadowRoot = this.attachShadow({mode: 'open'})
                             .appendChild(template.cloneNode(true));
         }
      }
   );

</script>

上記コードの実際の表示例は次のようになります。

山田 太郎 鈴木 花子

1つ目のslot要素には山田太郎が挿入され、slot属性が指定された鈴木花子は挿入されません。

2つ目のslot要素には値が挿入されないため、slot要素内のテキスト(既定のテキスト2)が表示されています。

複数の値を挿入する場合

name属性が指定された1つのslot要素に対し、複数の値を挿入することもできます。

<template id="my-template3">

   <style>
   div {
      margin: 0 0 1.2em;
      border: 1px #c0c0c0 solid;
      font-weight: bold;
   }
   </style>

   <div>
      <p><slot name="test">既定のテキスト</slot></p>
   </div>

</template>


<my-element3>
<span slot="test">その1</span>
<span slot="test">その2</span>
<span slot="test">その3</span>
<span>その4</span>
</my-element3>


<script>

   customElements.define('my-element3',
      class extends HTMLElement {
         constructor() {
            super();
            var template = document.getElementById('my-template3').content;
            var shadowRoot = this.attachShadow({mode: 'open'})
                             .appendChild(template.cloneNode(true));
         }
      }
   );

</script>

上記コードの実際の表示例は次のようになります。

その1 その2 その3 その4
旧HTMLからの変更点
  • HTML LS:slot要素が定義されました。

使用例

写真表示用のコードをコンポーネント化した例
  • 以下は、details要素の使用例にあるメニュー風に作成した例をコンポーネント化したものになります。

<template id="photo-template">

   <style>
   dl {
      width: 260px;
      margin: 1em 0;
      padding: 10px;
      background-color: #ffffff;
   }
   dl dt  {
      margin: 0 0 5px;
   }
   dl dd  {
      margin: 0 0 5px;
   }
   dl dd:last-child  {
      margin: 0;
   }
   dl p {
      margin: 5px;
   }
   dl summary {
      padding: 3px;
      background-color: #f5f5f5;
   }
   dl summary:hover {
      text-decoration: underline;
      cursor: pointer;
   }
   </style>

   <dl>
   <dt><slot name="img"></slot></dt>
   <dd>
   <details>
   <summary>サイズ</summary>
   <p><slot name="size"></slot></p>
   </details>
   </dd>
   <dd>
   <details>
   <summary>撮影日</summary>
   <p><slot name="date"></slot></p>
   </details>
   </dd>
   <dd>
   <details>
   <summary>説明</summary>
   <p><slot name="description"></slot></p>
   </details>
   </dd>
   </dl>

</template>


<photo-element>
<span slot="img"><img src="image/alps.jpg" alt="北アルプス" width="260" height="160"></span>
<span slot="size">260×160</span>
<span slot="date">8月1日</span>
<span slot="description">北アルプスの室堂にて</span>
</photo-element>

<photo-element>
<span slot="img"><img src="image/firework.jpg" alt="花火" width="260" height="160"></span>
<span slot="size">260×160</span>
<span slot="date">8月2日</span>
<span slot="description">板橋の花火を撮影</span>
</photo-element>

<photo-element>
<span slot="img"><img src="image/sunset.jpg" alt="夕焼け" width="260" height="160"></span>
<span slot="size">260×160</span>
<span slot="date">7月18日</span>
<span slot="description">近所の土手から見た夕焼け</span>
</photo-element>


<script>

   customElements.define('photo-element',
      class extends HTMLElement {
         constructor() {
            super();
            var template = document.getElementById('photo-template').content;
            var shadowRoot = this.attachShadow({mode: 'open'})
                             .appendChild(template.cloneNode(true));
         }
      }
   );

</script>

表示例
北アルプス 260×160 8月1日 北アルプスの室堂にて 花火 260×160 8月2日 板橋の花火を撮影 夕焼け 260×160 7月18日 近所の土手から見た夕焼け