Web Components
Web Components are browser standards for creating reusable HTML elements with their own behavior, structure, and styling boundaries. They let a component work in ordinary HTML and across application frameworks.
itWeb development | OpenSkills.info
Course pathWalk it in order
Look it upDip in anytime
Go furtherLeaves this page
Don't Panic
Don't Panic — Web Components
Web Components are a set of browser standards for creating reusable HTML elements. Not a framework, not a library—actual browser APIs that let you define a custom tag, give it a lifecycle, and optionally hide its internals behind a shadow boundary. If you've ever wished you could invent <status-badge> and have it just work, this is the spec that makes that possible.
The concept you need to hold in your head: every web component is a host element sitting in the page's ordinary document tree, which is also called the light DOM. That host can attach a shadow root, creating an internal tree with its own style scope. Children of the host can be placed into named positions inside that tree through slots. That's it—two trees, one boundary, and a composition model that decides what renders where.
The four pieces are custom elements (bind a hyphenated tag to a class), shadow DOM (encapsulate internal DOM and styles), templates (store inert content for cloning), and slots (let callers inject content into specific positions). You don't have to use all four. A custom element without shadow DOM is perfectly valid. A shadow root without a custom element is possible too. Pick each piece for the boundary it creates.
Here's the part that surprises most people: shadow DOM is not a security boundary. It prevents your page's CSS from accidentally bleeding into a component and vice versa, which is genuinely useful. But any page script can reach into an open shadow root and poke at its internals. Closed mode hides the shadowRoot property, but it doesn't stop direct DOM interaction. If you need to sandbox untrusted code, you want an iframe, not a shadow root.
The real difficulty with web components isn't the API—it's accessibility. ARIA attributes that reference other elements by ID, like aria-labelledby or aria-describedby, break silently at shadow boundaries because IDs are scoped to their shadow root. A label inside one component cannot reach a description living in another. The platform's answer is ElementInternals, which lets a custom element set default accessibility semantics that yield to explicit consumer overrides. But wiring it up correctly—especially for cross-component references—takes deliberate work that the spec does not do for you.
Before reaching for a custom element, ask whether native HTML already solves the problem. A styled <button> or <select> comes with keyboard handling, focus management, form integration, and accessibility semantics that a custom implementation would need to reproduce and test. The cost of a web component isn't registration—it's the API surface you now have to design, document, version, and test in real browsers.
Start with the Debugging tab for a methodical order: confirm the module loaded, check the registry, verify the lifecycle, then inspect the shadow tree. The Landscape tab shows which libraries reduce boilerplate without replacing the browser's component model. The Timeline tracks how the standard evolved from early W3C drafts to cross-browser support with server-rendering and scoped registries.
Where this skill leads
Relevant careers
See how this topic contributes to broader role-level skill maps.
Sources
- https://developer.mozilla.org/en-US/docs/Web/API/Web_components
Supports
- Web Components combine custom elements, shadow DOM, templates, and slots
- The general implementation sequence from class and registration through optional shadow DOM, templates, and use in a page
- Lifecycle callback names and their triggers
- CSS selectors, parts, slots, and DOM interfaces associated with Web Components
- https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements
Supports
- Autonomous and customized built-in custom-element types
- Registration, upgrade, observed attributes, and lifecycle behavior
- Constructor and callback responsibilities
- https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM
Supports
- Host, shadow tree, shadow boundary, and shadow root terminology
- DOM and CSS encapsulation behavior
- Open and closed roots and declarative shadow DOM
- Constructed and declarative stylesheet choices
- https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots
Supports
- Template content is inert until used
- Named and default slot assignment
- Assigned nodes remain caller-owned light-DOM content
- Slot fallback and manual assignment concepts
- https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Shadow_parts
Supports
- The part attribute exposes selected shadow-tree nodes
- The ::part() pseudo-element styles an exposed part from outside the shadow root
- https://developer.mozilla.org/en-US/docs/Web/API/Event/composed
Supports
- The composed property determines whether an event propagates across a shadow boundary
- Composed and bubbling behavior are separate event choices
- Event retargeting and composed paths protect internal boundary details
- https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals
Supports
- ElementInternals enables custom elements to participate in HTML forms
- ElementInternals exposes accessibility information for custom elements
- https://html.spec.whatwg.org/multipage/custom-elements.html
Supports
- Valid custom-element names contain a hyphen under the naming grammar
- CustomElementRegistry define, get, and whenDefined behavior
- One definition per name and constructor in a registry
- Custom-element reactions, lifecycle, and upgrade algorithms
- https://html.spec.whatwg.org/multipage/scripting.html#the-template-element
Supports
- Template contents are represented by a template contents document fragment
- Declarative shadow-root attributes on template elements
- https://dom.spec.whatwg.org/#shadow-trees
Supports
- Shadow tree, host, root, slot assignment, retargeting, and event-path algorithms
- Slotting affects the flattened tree without transferring light-DOM ownership
- https://web.dev/articles/custom-elements-best-practices
Supports
- Custom elements are low-level and need an intentional public behavior contract
- Progressive enhancement, property and attribute behavior, event guidance, and accessibility considerations
- Shadow DOM is useful for style encapsulation
- https://www.w3.org/WAI/ARIA/apg/practices/read-me-first/
Supports
- Native HTML is preferred when it provides the needed semantics and behavior
- Custom widgets require keyboard behavior and tested accessibility semantics
- https://web.dev/articles/declarative-shadow-dom
Supports
- Declarative shadow DOM provides parser-created shadow roots for server-rendered content
- Chrome 90 and Edge 91 supported an early form and later versions adopted shadowrootmode
- Declarative shadow DOM became available across all three major browser engines in 2024
- https://github.com/sindresorhus/awesome
Supports
- The required discovery index links to the Awesome Web Components list
- https://github.com/web-padawan/awesome-web-components
Supports
- Curated discovery of Open Web Components testing, Web Test Runner, Storybook for Web Components, Web Component Analyzer, and Custom Elements Manifest
- Curated discovery of Lit, Stencil, FAST, Lion, Spectrum Web Components, UI5 Web Components, and Web Awesome ecosystem projects
- https://open-wc.org/guides/developing-components/testing/
Supports
- Open Web Components recommends Web Test Runner for testing components in real browsers
- The guide covers generated tests, browser choices, and watch mode
- https://modern-web.dev/docs/test-runner/overview/
Supports
- Web Test Runner runs web tests with real browser launchers
- It supports watch mode, coverage, module mocking, and isolated parallel runs
- https://storybook.js.org/docs/9/get-started/frameworks/web-components-vite
Supports
- Storybook provides a Web Components and Vite framework for isolated component development and testing
- https://www.npmjs.com/package/web-component-analyzer
Supports
- The analyzer extracts attributes, properties, methods, events, slots, CSS parts, and custom properties
- It accepts JavaScript and TypeScript and can emit documentation or JSON
- https://custom-elements-manifest.open-wc.org/
Supports
- Custom Elements Manifest tooling generates component metadata from source code
- Its ecosystem uses generated manifests and plugins for documentation and integrations
- https://lit.dev/docs/v3/
Supports
- Lit adds reactive state, scoped styles, and declarative templates to standard Web Components
- Lit components remain standard custom elements consumable in HTML and framework environments
- https://github.com/lit/lit
Supports
- Lit is open-source under the BSD 3-Clause license
- Lit includes reactive-element, rendering, localization, React integration, and server-rendering packages
- https://stenciljs.com/
Supports
- Stencil compiles standards-based custom elements from a TypeScript and JSX authoring model
- Stencil supports output for framework consumption
- https://github.com/stenciljs/core
Supports
- Stencil is an open-source component compiler distributed under the MIT license
- https://fast.design/docs/3.x/introduction/
Supports
- FAST Element adds attribute and property syncing, templates, updates, and style composition over Web Components
- FAST retains the browser custom-element model and supports framework or no-framework consumption
- https://github.com/microsoft/fast
Supports
- FAST is an open-source project distributed under the MIT license
- https://lion.js.org/guides/principles/
Supports
- Lion provides white-label Web Components intended for extension into a design system
- Lion focuses on accessible component behavior with a caller-supplied visual layer
- https://github.com/ing-bank/lion
Supports
- Lion is an open-source project distributed under the MIT license
- https://opensource.adobe.com/spectrum-web-components/
Supports
- Spectrum Web Components implements Adobe Spectrum with framework-agnostic custom elements
- The library uses LitElement and documents a broad component set
- https://github.com/adobe/spectrum-web-components
Supports
- Spectrum Web Components is open-source under the Apache 2.0 license
- https://ui5.github.io/webcomponents/docs/getting-started/components-APIs/
Supports
- UI5 Web Components expose properties, attributes, slots, events, methods, and getters through ordinary HTML elements
- UI5 Web Components can be created and manipulated through standard DOM operations
- https://github.com/UI5/webcomponents
Supports
- UI5 Web Components is open-source under the Apache 2.0 license
- https://webawesome.com/docs/usage/
Supports
- Web Awesome elements expose documented attributes, properties, events, methods, slots, and CSS parts
- Web Awesome custom elements require ordinary non-void closing tags
- https://webawesome.com/
Supports
- Web Awesome offers an open-source component library with free and paid tiers
- The component catalog is standards-based and framework-agnostic
- https://www.w3.org/TR/2012/WD-components-intro-20120522/
Supports
- W3C published the Introduction to Web Components Working Draft on 22 May 2012
- The early model combined templates, custom elements, shadow DOM, and imports
- https://www.w3.org/TR/2013/WD-html-templates-20130214/
Supports
- W3C published the HTML Templates Working Draft on 14 February 2013
- The draft specified parsed template content and later instantiation
- https://www.w3.org/TR/2013/WD-custom-elements-20130514/
Supports
- W3C published the Custom Elements Working Draft on 14 May 2013
- The draft covered constructors and custom-element behavior
- https://www.w3.org/TR/2013/WD-shadow-dom-20130514/
Supports
- W3C published the Shadow DOM Working Draft on 14 May 2013
- The draft formalized shadow trees and composition
- https://www.w3.org/standards/history/html-imports/
Supports
- W3C published an HTML Imports Working Draft on 11 March 2014
- W3C retired HTML Imports on 15 June 2023
- https://webkit.org/blog/4096/introducing-shadow-dom-api/
Supports
- WebKit announced basic nightly support for the slot-based shadow DOM API on 26 October 2015
- Slots compose light-DOM children into positions in a shadow tree
- Shadow DOM provides style isolation but not an iframe-like security boundary
- https://webkit.org/blog/7027/introducing-custom-elements/
Supports
- WebKit announced Custom Elements API support in Safari Technology Preview 18 on 18 November 2016
- The version-one API uses customElements.define and lifecycle callbacks
- https://webkit.org/blog/7477/new-web-features-in-safari-10-1/
Supports
- Safari 10.1 shipped Custom Elements support in March 2017
- https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/63
Supports
- Firefox 63 was released on 23 October 2018
- Firefox 63 enabled Shadow DOM and Custom Elements by default
- https://blogs.windows.com/msedgedev/2020/01/15/upgrading-new-microsoft-edge-79-chromium/
Supports
- Microsoft released its first stable Chromium-based Edge build on 15 January 2020
- The release was Microsoft Edge 79 stable
- https://chromereleases.googleblog.com/2021/04/
Supports
- Chrome 90 stable for desktop was updated on 26 April 2021
- https://webkit.org/blog/13966/webkit-features-in-safari-16-4/
Supports
- Safari 16.4 shipped on 27 March 2023
- Safari 16.4 added declarative shadow DOM and ElementInternals
- https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/123
Supports
- Firefox 123 was released on 20 February 2024
- Firefox 123 added the shadowrootmode template attribute for declarative shadow DOM
- https://nolanlawson.com/2022/11/28/shadow-dom-and-accessibility-the-trouble-with-aria/
Supports
- ARIA IDREF attributes break at shadow boundaries because IDs are scoped to their shadow root
- The ARIA mixin properties that accept element references solve this for ancestor-descendant relationships
- Cross-root ARIA remains an unsolved spec problem as of the analysis date
- https://www.web-framework-components.com/core-architecture-lifecycle-management/accessibility-and-focus-management/exposing-aria-semantics-with-elementinternals/
Supports
- ElementInternals sets default accessibility semantics that yield to explicit host attributes
- ARIA attributes on the host element are writable by any consumer or framework
- Mixing internals defaults with host-attribute fallbacks creates precedence bugs
