Templates & Web Components

The <template> element holds HTML that isn't rendered until a script copies it into the page — ideal for repeated items like cards or table rows. Combined with custom elements and the shadow DOM, templates let you create your own reusable HTML tags: web components.

The template element

Try it yourself
Result

Content inside <template> is parsed but inert: it isn't shown, images don't load and scripts don't run. A script clones template.content, fills in the data with textContent (safe from injection) and adds it to the page. The structure stays in HTML, where it's easy to read and edit.

Custom elements

You can define your own HTML elements. Their names must contain a hyphen, to avoid clashing with future built-in elements:

Try it yourself
Result

customElements.define registers the class. connectedCallback runs whenever an instance is added to the page. From then on, <greeting-badge> works like any other tag — in HTML, in JavaScript, and in any framework.

Shadow DOM: encapsulated styles

A component can have its own private DOM tree — a shadow root — whose styles don't leak out, and page styles don't leak in:

Try it yourself
Result

The <slot> element marks where the component's children (the light DOM) appear inside its shadow DOM. Named slots (<slot name="footer"> paired with slot="footer" on a child) allow several insertion points.

Declarative shadow DOM

A shadow root can also be written directly in HTML, so components can be rendered on the server without JavaScript:

Try it yourself
Result

When to use web components

  • Design systems shared across teams using different frameworks — a <company-button> works in React, Vue and plain HTML alike.
  • Embeddable widgets — maps, players and chat boxes that must not be affected by the host page's CSS.
  • Progressive enhancement — wrapping ordinary HTML in a custom element that adds behaviour once the script loads.

Libraries such as Lit reduce the boilerplate of writing components. For a full single-page application, frameworks like React, Vue and Angular remain more common.

Accessibility reminders

Custom elements start with no built-in semantics — a <fancy-button> isn't a button to assistive technology. Either put real elements (like <button>) inside the component, or provide roles, keyboard handling and focus management yourself.

Try it yourself

Try it yourself
Result