This is an experimental technology
Check the Browser compatibility table carefully before using this in production.
The <slot>
—part of the Web Components technology suite—is a placeholder inside a web component that you can fill with your own markup, which lets you create separate DOM trees and present them together.
Content categories | Flow content, phrasing content |
---|---|
Permitted content | Transparent |
Tag omission | None, both the starting and ending tag are mandatory. |
Permitted parents | Any element that accepts phrasing content |
Permitted ARIA roles | None |
DOM interface | HTMLSlotElement |
This element includes the global attributes.
name
<slot>
element with a name
attribute.Let’s make an example using the <slot>
element along with the <template>
element.
The following set of code snippets show how to use the <slot>
element together with the <template>
element and some JavaScript to:
<element-details>
element with named slots in its shadow root
<element-details>
element in such a way that, when used in documents, it is rendered from composing the element’s content together with content from its shadow root—that is, pieces of the element’s content are used to fill in named slots in its shadow root
Note that while it is technically possible to use <slot>
element without a <template>
element, e.g., within say a regular <div>
element, and still take advantage of the place-holder features of <slot>
for Shadow DOM content, and doing so may indeed avoid the small trouble of needing to first access the template element's content
property (and clone it), it is generally more practical to add slots within a <template>
element since it isn't as common of a need to define a pattern based on an already-rendered element and even if it is not already rendered, the purpose of the container as a template should be more semantically clear when using the <template>
proper. In addition, <template>
can have items directly added to it like <td>
which would disappear when added to a <div>
.
First let’s use the <slot>
element within a <template>
element to create a new “element-details-template” document fragment containing some named slots.
<template id="element-details-template"> <style> details {font-family: "Open Sans Light",Helvetica,Arial} .name {font-weight: bold; color: #217ac0; font-size: 120%} h4 { margin: 10px 0 -8px 0; } h4 span { background: #217ac0; padding: 2px 6px 2px 6px } h4 span { border: 1px solid #cee9f9; border-radius: 4px } h4 span { color: white } .attributes { margin-left: 22px; font-size: 90% } .attributes p { margin-left: 16px; font-style: italic } </style> <details> <summary> <span> <code class="name"><<slot name="element-name">NEED NAME</slot>></code> <i class="desc"><slot name="description">NEED DESCRIPTION</slot></i> </span> </summary> <div class="attributes"> <h4><span>Attributes</span></h4> <slot name="attributes"><p>None</p></slot> </div> </details> <hr> </template>
That <template>
element has several features:
<template>
has a <style>
element with a set of CSS styles that are scoped just to the document fragment the <template>
creates.<template>
uses <slot>
and its name
attribute to make three named slots: <slot name="element-name">
<slot name="description">
<slot name="attributes">
<template>
wraps the named slots in a <details>
element.Next, let’s create a new custom element named <element-details>
and use Element.attachShadow
to attach to it, as its shadow root, that document fragment we created with our <template>
element above.
customElements.define('element-details', class extends HTMLElement { constructor() { super(); var template = document .getElementById('element-details-template') .content; const shadowRoot = this.attachShadow({mode: 'open'}) .appendChild(template.cloneNode(true)); } })
Now let’s take that <element-details
element and actually use it in our document.
<element-details> <span slot="element-name">slot</span> <span slot="description">A placeholder inside a web component that users can fill with their own markup, with the effect of composing different DOM trees together.</span> <dl slot="attributes"> <dt>name</dt> <dd>The name of the slot.</dd> </dl> </element-details> <element-details> <span slot="element-name">template</span> <span slot="description">A mechanism for holding client- side content that is not to be rendered when a page is loaded but may subsequently be instantiated during runtime using JavaScript.</span> </element-details>
About that snippet, notice these points:
<element-details>
elements which both use the slot
attribute to reference the named slots "element-name"
and "description"
we put in the <element-details>
shadow root .<element-details>
elements references the "attributes"
named slot. The second <element-details>
element lacks any reference to the "attributes"
named slot.<element-details>
element references the "attributes"
named slot using a <dl>
element with <dt>
and <dd>
children.Finishing touch: A tiny bit more CSS for the <dl>
, <dt>
, and <dd>
elements in our doc.
dl { margin-left: 6px; } dt { font-weight: bold; color: #217ac0; font-size: 110% } dt { font-family: Consolas, "Liberation Mono", Courier } dd { margin-left: 16px }
Finally let’s put all the snippets together and see what the rendered result looks like.
Screenshot | Live sample |
---|---|
About that rendered result, notice these points:
<element-details>
element in the document do not directly use the <details>
element, they get rendered using <details>
because the shadow root causes them to get populated with that.<details>
output, the content in the <element-details>
elements fills the named slots from the shadow root. In other words, the DOM tree from the <element-details>
elements get composed together with the content of the shadow root.<element-details>
elements, an Attributes heading gets automatically added from the shadow root before the position of the "attributes"
named slot.<element-details>
has a <dl>
element which explicitly references the "attributes"
named slot from its shadow root, the contents of that <dl>
replace the "attributes"
named slot from the shadow root.<element-details>
doesn’t explicitly reference the "attributes"
named slot from its shadow root, its content for that named slot gets filled with the default content for it from the shadow root.Specification | Status | Comment |
---|---|---|
HTML Living Standard The definition of '<slot>' in that specification. | Living Standard | |
DOM The definition of 'Slots' in that specification. | Living Standard |
Feature | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
Basic support | 53 | No | No | No | 40 | 10 |
name |
53 | No | No | No | 40 | 10 |
Feature | Android webview | Chrome for Android | Edge mobile | Firefox for Android | IE mobile | Opera Android | iOS Safari |
---|---|---|---|---|---|---|---|
Basic support | 53 | 53 | No | No | No | 40 | 10.1 |
name |
53 | 53 | No | No | No | 40 | 10.1 |
© 2005–2018 Mozilla Developer Network and individual contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot