Making & using web components.
slot
ElementInternals
:has-slotted
Using custom elements, that you or someone else defined.
<my-switch start="On" end="Off">Wi-Fi</my-switch>
Defining custom elements for use by others.
class MyElement extends HTMLElement { … } customElements.define("my-element", MyElement);
Create web components declaratively through HTML, with or without JS.
<definition name="progress-ring"> <template shadowmode="open"> <div id="base" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="{{root.attributes.percentage.value}}"> <slot>{{ root.attributes.percentage.value }}%</slot> </div> <style>#base { /* ... */ }</style> </template> </definition> <progress-ring value="50"></progress-ring>
Allow multiple custom element definitions for a single tag name to exist within a page.
const registry = new CustomElementRegistry(); registry.define('sub-element', SubElement);
Encapsulate elements not visible from the outside, and style them with CSS not affecting the rest of the page.
this.shadowRoot = this.attachShadow({mode: "open"});
Define shadow trees with HTML, such as when server-side-rendering web components.
<host-element> <template shadowrootmode="open"> <!-- Shadow content --> </template> </host-element>
Replacing predefined parts of a component UI with your own elements.
<my-switch> Wi-Fi <i slot="start" class="icon-on">On</i> <i slot="end" class="icon-off">Off</i> </my-switch>
A way to assign elements to slots manually via JS, so that slot assignment does not have to be managed by the component consumers.
this.attachShadow({mode: "open", slotAssignment: "manual" }); let headerSlot = this.shadowRoot.querySelector("slot[name=header]"); let header = this.querySelector("header"); if (header) headerSlot.assign(header);
Assign hidden semantics to custom elements, facilitating accessibility and allowing them to participate fully in forms.
this._internals = this.attachInternals(); this._internals.role = "progressbar";
A way to “redirect” id references to a component to elements in its shadow DOM (for ARIA, labels, popovers etc).
this.attachShadow({ mode: "open", referenceTarget: "real-input", }); this.shadowRoot.innerHTML = `<input id="real-input">`;
CSS pseudo-class that allows targeting <slot> elements only when they have slotted nodes.
<slot>
slot[name=icon]:not(:has-slotted) + .icon-label { display: none; }
* { margin: 0 }
::slotted()
:host
::slotted(ul) > li