Shadow DOM Slots

Introduction to Slots

Slots are part of the Shadow DOM technology, allowing developers to design components with a predefined insertion point for user-defined content. Slots provide a way to create placeholder elements inside your custom elements that can be filled with custom markup provided by the users of your component. This mechanism allows for flexible content distribution, enabling the creation of complex, reusable components that can accept varied content structures.

A slot is defined in the shadow DOM and can be named or unnamed. When content is added to a custom element, it gets distributed to the corresponding slot, making it appear as part of the component’s shadow DOM.

Using Slots in Custom Elements

There are two types of slots:

  • default slots
  • named slots.

Default Slots

A default slot accepts any content that is not assigned to a named slot. To define a default slot in your custom element, simply include a <slot> tag without any attributes in the component’s template. This creates a slot where all unassigned content will be placed:

html
	<slot></slot>

Named Slots For more control over where specific content should be placed, you can use named slots. Named slots allow you to define multiple placeholders in your component and specify exactly where certain pieces of content should go. To create a named slot, add a name attribute to the <slot> element:

html
	<slot name="header"></slot>
	<slot name="footer"></slot>

When using the component, users can assign content to these named slots by setting the slot attribute on the relevant elements. For example:

This is the header content

This is the footer content

In this setup, the content provided with the slot=“header” attribute will be placed in the header slot, and the content with slot=“footer” will be placed in the footer slot.

Practical Example

Let’s create a simple dialog box component that utilizes slots to allow users to customize the header, content, and footer.

Step 1: Define the Dialog Component

Create a file named DialogBox.js and add the following code to define the DialogBox custom element:

javascript
	// DialogBox.js
	class DialogBox extends HTMLElement {
	  constructor() {
	    super();
	    this.attachShadow({ mode: 'open' }).innerHTML = `
	      <style>
	        :host { display: block; background: white; border: 2px solid black; padding: 16px; }
	        ::slotted(h2) { color: darkblue; }
	        ::slotted(p) { font-size: 16px; }
	      <\/style>
	      <slot name="header"></slot>
	      <div class="content">
	        <slot></slot> <!-- Default slot for content -->
	      </div>
	      <slot name="footer"></slot>
	    `;
	  }
	}
	
	customElements.define('dialog-box', DialogBox);

This component defines three slots: one named header, one default slot for the main content, and one named footer. The ::slotted() CSS pseudo-element is used to style the slotted content differently based on its type.

Step 2: Use the Dialog Component in Your Application

Include the DialogBox component in your HTML and provide content for each slot:

html
	<dialog-box>
	  <h2 slot="header">Dialog Header</h2>
	  <p>This is the main content of the dialog.</p>
	  <div slot="footer">Footer content here</div>
	</dialog-box>

Summary

Slots are a versatile feature in Web Components, enabling you to build complex, customizable components. By defining slots in your components, you allow users to inject custom content into predefined places within your component, enhancing the component’s flexibility and reusability. This lesson covered the basics of using slots, including defining named and unnamed slots and styling slotted content. Slots empower you to design components that can be easily adapted to different contexts, making your web applications more dynamic and engaging.

Reference