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.
7. Security and Accessibility
- Use safe DOM methods when rendering untrusted content.
- Give controls accessible names and meaningful semantics.
- Do not assume Shadow DOM makes a component secure.
- Ensure keyboard interaction works correctly.
- Consider form participation and browser support when building advanced custom controls.
Common Mistakes
- Forgetting the hyphen in a custom element name.
- Registering the same custom element name more than once.
- Assuming template content appears automatically.
- Inserting untrusted content into innerHTML.
- Assuming Shadow DOM automatically provides accessibility.
Practice Exercises
- Create a course card template and clone it with JavaScript.
- Build a custom element called student-card.
- Add a title attribute to a custom element and display its value.
- Create a component with an open Shadow DOM root.
- Build a component with a named title slot and a default slot.
Revision Quiz
- Does template content render immediately by default?
- What character pattern is required in a custom element name?
- Which method registers a custom element?
- Which method creates a Shadow DOM root?
- What is the purpose of a slot?
- Does Shadow DOM provide a security boundary?
Answer Key and Explanations
- No. Template content is inert until it is used, commonly by cloning it.
- A hyphen — Valid custom element names contain a hyphen.
- customElements.define() — It registers the custom element name and constructor.
- attachShadow() — It attaches a Shadow DOM root to a supported host element.
- To display supplied content at an insertion point — Slots support component composition.
- No. Shadow DOM encapsulates structure and styling; it does not make content secure against malicious code.