What are Web Components?
Web Components are a native way for web developers to build user interfaces. They're built right into your browser so you don't have to download any framework to get started. Web Components fit right into your existing HTML today. If you've got a server that can render HTML, then you can render Web Components.
Web Components allow you to extend the vocabulary of your HTML. You can define new behaviors that go beyond the built
in tags. New features such as <slide-out-menu>
or <stop-watch>
are at your finger tips. JavaScript can drive these
definitions, allowing advanced behaviors and interactions.
Custom Element tag names are required to include a dash (-
) in their name. Having a dash makes them easier to tell
apart from native (built-in) elements. New built-ins will never have a dash, and so won't conflict.
Here's an example of a web component that renders a timer. It defines its own styles, it renders into a ShadowDOM, and has its own private state. It makes use of the lifecycle callbacks to know when to start counting. These are all built in web platform features.
// Create a new stylesheet that can be shared by all `stop-watch` elements const styles = new CSSStyleSheet() styles.replaceSync(` :host { font-size: var(--font-size-3); font-style: italic; } `) // Define the StopWatch element Class class StopWatchElement extends HTMLElement { static define(tag = "stop-watch") { customElements.define(tag, this) } // Give this element its own encapsulated DOM shadowRoot = this.attachShadow({ mode: "open" }) // Initialize private state #start = Date.now() connectedCallback() { // Add the shared styles this.shadowRoot.adoptedStyleSheets = [styles] // Start the timer this.#tick() } #tick() { const milliseconds = Date.now() - this.#start const minutes = String(Math.floor(milliseconds / (1000 * 60))).padStart(2, "0") const seconds = String(Math.floor((milliseconds / 1000) % 60)).padStart(2, "0") const hundredths = String(Math.floor((milliseconds % 1000) / 10)).padStart(2, "0") this.shadowRoot.replaceChildren(`${minutes}:${seconds}:${hundredths}`) // Schedule next update requestAnimationFrame(() => this.#tick()) } } // Register the element with the Custom Element Registry StopWatchElement.define()
<stop-watch role="timer"></stop-watch>
Result
Let's find out more about how to build this component...