CHAPTER 7 – Interactive Elements & Web Components
Checking engine…

7.4 — Web Components Basics: <template>, <slot> & Custom Elements

Web Components bring true modularity to HTML. The <template> element stores dormant markup that can be cloned later; <slot> provides content insertion points; and the is attribute allows standard elements to be extended with custom behaviour. Together they enable reusable, encapsulated UI pieces directly in the markup.

Pillar 1: The <template> Element – Inert Blueprint Storage

The <template> is a container whose entire contents are inert. The browser:

  • Parses and validates the internal HTML, but does not render it.
  • Does not load any resources (images, scripts, stylesheets) inside the template.
  • Creates a DocumentFragment that can be cloned and inserted into the live DOM via JavaScript, at which point the content becomes active.

This makes <template> the perfect vault for repeating structures: table rows, list items, modal skeletons, card layouts.

<template id="user-row">
  <tr>
    <td class="name"></td>
    <td class="role"></td>
  </tr>
</template>

The template itself is invisible – nothing appears on screen until a script clones it. The markup is safe, parsed, and ready.

Pillar 2: The <slot> Element – Content Projection

A <slot> acts as a placeholder inside a component. When the component is used, content from the light DOM (the surrounding page) can flow into the slot. There are two kinds:

  • Default slot – has no name attribute. It captures any content not explicitly assigned to a named slot.
  • Named slot – has a name attribute (e.g., name="title"). Only content with a matching slot attribute on the consuming side will be projected into it.

You can also provide fallback content between the opening and closing slot tags – this is displayed only if nothing is projected into the slot.

<template id="card">
  <div class="card">
    <header>
      <slot name="title">Default Title</slot>
    </header>
    <section>
      <slot>Default body text.</slot>
    </section>
  </div>
</template>

When consumed (e.g., via custom element or JS clone), the user can supply their own title and body, overriding the fallbacks.

Pillar 3: Custom Elements via the is Attribute

A custom element can either be autonomous (a new tag like <my-widget>) or a customized built‑in that extends an existing HTML element. The latter uses the is attribute on a standard tag:

<button is="fancy-button">Click me</button>

This tells the browser: “treat this button as a button (all native behaviour and accessibility), but also apply the custom element class registered for fancy-button.” The custom class (defined in JavaScript) can add extra styling, attach shadow DOM, or inject behaviour – yet the element remains fully accessible and functional even if the script fails.

In the live demo below, a small script registers fancy-button to demonstrate the concept. The button still works without the script; with it, it gains a shadow DOM and a custom style.

Live Demo: <button is="fancy-button">

The button above is a standard <button> extended by a custom element class – styling and behaviour come from the registered definition.

The is attribute is the HTML‑side bridge that connects existing semantic elements to powerful custom logic without sacrificing accessibility or graceful degradation.

Enterprise Blueprint – Reusable System Card with Named Slots and Custom Button

The following code assembles all three pillars: a <template> containing a card structure with named and default slots, and a custom button that could eventually be wired to interactive logic. The template remains invisible until cloned; the button is ready to be extended.

<!-- Inert blueprint -->
<template id="system-card-blueprint">
  <div class="card-envelope">
    <header class="card-header-zone">
      <slot name="card-title">Fallback System Heading</slot>
    </header>
    <section class="card-body-zone">
      <slot></slot>
    </section>
  </div>
</template>

<!-- Custom button (HTML side) -->
<button is="fancy-button">Click me</button>

The blueprint is fully parsed, validated, and ready to be instantiated at any time. The custom button retains all native button semantics while opening the door to rich component behaviour – all defined in pure HTML plus a single attribute.

TAKEAWAY

Web Components are not a framework – they are a native browser capability. Use <template> to store reusable markup, <slot> to define content projection points (named or default), and the is attribute to extend existing HTML elements with custom logic. Together they form the foundation of a modular, maintainable, and future‑proof HTML architecture.

Checking engine…