<slot>
Overview
The <slot>
element acts as a placeholder within a web component's Shadow DOM, which can be filled with custom markup from the main document. This allows for a modular design where separate DOM trees can be composed together.
Web Components are a collection of web platform APIs that let developers make custom, reusable HTML tags for web pages and apps.
Central to Web Components is the Shadow DOM, which encapsulates parts of a web page, keeping them separate from the main document's DOM. The <slot>
element works with the Shadow DOM, letting developers adapt a component's internal structure based on where it's used.
Examples and Usage
To further understand the <slot>
element and its interplay with Web Components and the Shadow DOM, let's explore an illustrative example. Specifically, we'll create a customizable user card that can display different user names and descriptions, showcasing the flexibility offered by the <slot>
element.
<!-- Define the template with slots -->
<template id="user-card-template">
<style>
div.card {
border: 1px solid #ccc;
padding: 10px;
margin: 10px;
width: 200px;
border-radius: 8px;
box-shadow: 2px 2px 12px #aaa;
}
h2, p {
margin: 5px 0;
}
</style>
<div class="card">
<!-- Slot for user's name -->
<h2><slot name="user-name">Default User</slot></h2>
<!-- Slot for user's description -->
<p><slot name="user-description">No description provided.</slot></p>
</div>
</template>
<script>
// Create the Web Component
class UserCard extends HTMLElement {
constructor() {
super();
const templateContent = document.getElementById('user-card-template').content;
this.attachShadow({mode: 'open'}).appendChild(templateContent.cloneNode(true));
}
}
customElements.define('user-card', UserCard);
</script>
<!-- Use the Web Component -->
<user-card>
<span slot="user-name">John Doe</span>
<span slot="user-description">A web developer from NYC.</span>
</user-card>
We start with the
<template>
element.<template>
allows declaring fragments of markup that aren't rendered initially but can be used later on. In our case, this template contains the structure and styling of ouruser-card
.Within this template, two
<slot>
elements are specified: one for the user's name (<slot name="user-name">
) and another for their description (<slot name="user-description">
).In the JavaScript section, we define our Web Component (
UserCard
). The constructor of this component fetches the content of our template, then attaches a Shadow DOM to the component, and finally appends the template's content to this Shadow DOM.In the main HTML, we utilize the Web Component. Here, we provide custom content (John Doe & his description) for the slots using the
slot
attribute on<span>
elements. This content will replace the placeholders set within the component's shadow DOM.
When displayed, content from the main document (John Doe & his description) fills the slots in the user-card
component. If a slot lacks content, its default, like "Default User" or "No description provided", appears.
An important distinction to understand is the difference between the <slot>
element and the slot
attribute. The former, within the component's template, sets placeholders. The latter, on content in the main document, determines which placeholder the content should occupy.
For the sake of brevity and clarity, we've included everything within a single file. In larger projects, it's common to use distinct files for better organization. Web Components also provide mechanisms to import and reuse components across different parts of a project, but that's a topic that delves deeper into the intricacies of Web Components beyond just the <slot>
element.
Attribute Breakdown
In addition to global attributes, the <slot>
element has a name
attribute.
Attribute | Description |
---|---|
name | Specifies a name for the slot, allowing the main document to target specific slots inside the Shadow DOM. |
Accessibility Aspects
The <slot>
element doesn't possess specific accessibility considerations. It doesn't correlate with any particular ARIA role and doesn't utilize aria-*
attributes.
Associated Elements
<template>
Additional Notes
If elements don't specify which slot they belong to or don't match any named slots, they get placed inside a default slot. This is a slot without a
name
attribute. If there's no such default slot, the content won't be displayed.It's possible for several elements to target and be displayed in a single named slot. They'll appear in the order they're present in the original document.
While the content inside a slot can be styled using the main document's styles, the slot itself can't be styled directly. You can style slotted content using the
::slotted()
pseudo-element from within the Shadow DOM. To style deeper elements inside the shadow DOM from the main document, use thepart
attribute in conjunction with the::part() pseudo-element
.
Browser Compatibility
For a detailed breakdown of specific browser nuances and older version support refer to the first link in the Useful Resources below.
Browser | Chrome | Edge | Safari | Firefox | Opera | Internet Explorer |
---|---|---|---|---|---|---|
Support | Yes | Yes* | Yes | Yes | Yes | No |
Useful Resources
The HTML Living Standard Specification: slot
The HTML Living Standard DOM Specification: slots