Section 31: Templates, Slots, Custom Elements and Web Components
Learning Objectives
- Understand the template element.
- Learn what custom elements are.
- Understand slots and the Shadow DOM.
- Learn how Web Components extend HTML with reusable interface elements.
1. What Is the template Element?
The template element holds HTML that is not rendered immediately. JavaScript can clone its content and insert it into the document when needed.
<template id="course-template">
<article class="course-card">
<h2>Course Title</h2>
<p>Course description goes here.</p>
</article>
</template>
<div id="course-list"></div>
<script>
const template = document.querySelector("#course-template");
const list = document.querySelector("#course-list");
const card = template.content.cloneNode(true);
card.querySelector("h2").textContent = "HTML Mastery";
card.querySelector("p").textContent =
"Learn HTML through practical lessons and projects.";
list.append(card);
</script>2. What Are Custom Elements?
Custom elements let developers define new HTML element names and their behavior using JavaScript. A custom element name must contain a hyphen.
<course-card></course-card>
<script>
class CourseCard extends HTMLElement {
connectedCallback() {
this.textContent = "HTML Mastery Course";
}
}
customElements.define("course-card", CourseCard);
</script>In this example, the browser upgrades course-card after its definition is registered. The connectedCallback method runs when the element is connected to the document.
3. A Reusable Custom Element
<course-card title="HTML Mastery"></course-card>
<course-card title="CSS Fundamentals"></course-card>
<script>
class CourseCard extends HTMLElement {
connectedCallback() {
const title = this.getAttribute("title") || "Untitled Course";
this.textContent = title;
}
}
customElements.define("course-card", CourseCard);
</script>This example reads a title attribute. For complex components, avoid repeatedly replacing the element's contents whenever it reconnects. Use lifecycle methods carefully and manage event listeners and state appropriately.
4. What Is Shadow DOM?
The Shadow DOM provides an encapsulated DOM subtree for a component. It can help isolate component markup and styles from the surrounding document, although it is not a security boundary.
<script>
class GreetingCard extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: "open" });
shadow.innerHTML = `
<style>
article {
border: 1px solid #999;
padding: 1rem;
border-radius: 8px;
}
</style>
<article>Hello from a Web Component!</article>
`;
}
}
customElements.define("greeting-card", GreetingCard);
</script>
<greeting-card></greeting-card>This small demonstration uses a static template string. Never interpolate untrusted user input into innerHTML without suitable sanitization. For complex or dynamic content, prefer safe DOM APIs such as textContent and createElement.
5. What Are Slots?
Slots allow a component using Shadow DOM to display content supplied by the page author.
<script>
class CoursePanel extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: "open" });
shadow.innerHTML = `
<style>
section { border: 1px solid #aaa; padding: 1rem; }
</style>
<section>
<h2><slot name="title">Default title</slot></h2>
<slot>Default content</slot>
</section>
`;
}
}
customElements.define("course-panel", CoursePanel);
</script>
<course-panel>
<span slot="title">HTML Mastery</span>
<p>Learn HTML step by step.</p>
</course-panel>The named slot receives the element with slot="title". The unnamed slot receives the remaining eligible light-DOM content.
6. The Web Components Family
- Custom Elements: define reusable custom HTML elements.
- Shadow DOM: encapsulate a component's DOM and styles.
- HTML Templates and Slots: prepare reusable markup and provide insertion points.
These technologies can be used together, but not every custom element needs Shadow DOM or a template.