A Complete Introduction to Web Components

Web Components, featured image, illustration.

We all have projects we’d instead not work on. The code has become unmanageable, the scope evolved, quick fixes applied on top of other fixes, and the structure collapsed under its weight of spaghetti code. Coding can be a messy business.

Projects benefit from using simple, independent modules which have a single responsibility. Modular code is encapsulated, so there’s less need to worry about the implementation. As long as you know what a module will output when given a set of inputs, you don’t necessarily need to understand how it achieved that goal.

Applying modular concepts to a single programming language is straightforward, but web development requires a diverse mix of technologies. Browsers parse HTML , CSS, and JavaScript to render the page’s content, styles, and functionality.

They don’t always mix easily because:

  • Related code can be split between three or more files, and
  • Global styles and JavaScript objects can interfere with each other in unexpected ways.

These problems are in addition to those encountered by language runtimes, frameworks , databases, and other dependencies used on the server.

Check Out Our Video Guide to Web Components

What are web components.

A Web Component is a way to create an encapsulated, single-responsibility code block that can be reused on any page.

Consider the HTML <video> tag. Given a URL , a viewer can use controls such as play, pause, move back, move forward, and adjust the volume.

Styling and functionality are provided, although you can make modifications using various attributes and JavaScript API calls. Any number of <video> elements can be placed inside other tags, and they won’t conflict.

What if you require your own custom functionality? For example, an element showing the number of words on the page? There’s no HTML <wordcount> tag (yet).

Frameworks such as React and Vue.js allow developers to create web components where the content, styling, and functionality can be defined in a single JavaScript file. These solve many complex programming problems but bear in mind that:

  • You must learn how to use that framework and update your code as it evolves.
  • A component written for one framework is rarely compatible with another.
  • Frameworks rise and wane in popularity. You’ll become dependent on the whims and priorities of the development team and users.
  • Standard Web Components can add browser functionality, which is difficult to achieve in JavaScript alone (such as the Shadow DOM).

Fortunately, popular concepts introduced in libraries and frameworks usually make their way into web standards. It’s taken some time, but Web Components have arrived.

A Brief History of Web Components

Following many vendor-specific false starts, the concept of standard Web Components was first introduced by Alex Russell at the Fronteers Conference in 2011 . Google’s Polymer library (a polyfill based on the current proposals) arrived two years later, but early implementations did not appear in Chrome and Safari until 2016.

Browser vendors took time to negotiate the details, but Web Components were added to Firefox in 2018 and Edge in 2020 (when Microsoft switched to the Chromium engine).

Understandably, few developers have been willing or able to adopt Web Components, but we have finally reached a good level of browser support with stable APIs. Not everything is perfect, but they’re an increasingly viable alternative to framework-based components.

Even if you’re not willing to dump your favorite just yet, Web Components are compatible with every framework, and the APIs will be supported for years to come.

Repositories of pre-built Web Components are available for everyone to take a look at:

  • WebComponents.org
  • The Component Gallery
  • generic-components
  • web-components-examples
  • awesome-standalones
  • accessible_components
  • Kickstand UI

…but writing your own code is more fun!

This tutorial provides a complete introduction to Web Components written without a JavaScript framework. You will learn what they are and how to adapt them for your web projects. You’ll need some knowledge of HTML5 , CSS, and JavaScript.

Getting Started With Web Components

Web Components are custom HTML elements such as <hello-world></hello-world> . The name must contain a dash to never clash with elements officially supported in the HTML specification.

You must define an ES2015 class to control the element. It can be named anything, but HelloWorld is common practice. It must extend the HTMLElement interface , which represents the default properties and methods of every HTML element.

Note: Firefox allows you to extend specific HTML elements such as HTMLParagraphElement, HTMLImageElement, or HTMLButtonElement. This is not supported in other browsers and does not allow you to create a Shadow DOM.

To do anything useful, the class requires a method named connectedCallback() which is invoked when the element is added to a document:

In this example, the element’s text is set to “Hello World.”

The class must be registered with the CustomElementRegistry to define it as a handler for a specific element:

The browser now associates the <hello-world> element with your HelloWorld class when your JavaScript is loaded (e.g. <script type="module" src="./helloworld.js"></script> ).

You now have a custom element!

CodePen demonstration

This component can be styled in CSS like any other element:

Adding Attributes

This component isn’t beneficial since the same text is output regardless. Like any other element, we can add HTML attributes:

This could override the text so “Hello Craig!” is displayed. To achieve this, you can add a constructor() function to the HelloWorld class, which is run when each object is created. It must:

  • call the super() method to initialize the parent HTMLElement, and
  • make other initializations. In this case, we’ll define a name property that is set to a default of “World”:

Your component only cares about the name attribute. A static observedAttributes() property should return an array of properties to observe:

An attributeChangedCallback() method is called when an attribute is defined in the HTML or changed using JavaScript. It’s passed the property name, old value, and new value:

In this example, only the name property would ever be updated, but you could add additional properties as necessary.

Finally, you need to tweak the message in the connectedCallback() method:

Lifecycle Methods

The browser automatically calls six methods throughout the lifecycle of the Web Component state. The full list is provided here, although you have already seen the first four in the examples above:

constructor()

It’s called when the component is first initialized. It must call super() and can set any defaults or perform other pre-rendering processes.

static observedAttributes()

Returns an array of attributes that the browser will observe.

attributeChangedCallback(propertyName, oldValue, newValue)

Called whenever an observed attribute is changed. Those defined in HTML are passed immediately, but JavaScript can modify them:

The method may need to trigger a re-render when this occurs.

connectedCallback()

This function is called when the Web Component is appended to a Document Object Model. It should run any required rendering.

disconnectedCallback()

It’s called when the Web Component is removed from a Document Object Model. This may be useful if you need to clean up, such as removing stored state or aborting Ajax requests .

adoptedCallback()

This function is called when a Web Component is moved from one document to another. You may find a use for this, although I’ve struggled to think of any cases!

How Web Components Interact With Other Elements

Web Components offer some unique functionality you won’t find in JavaScript frameworks.

The Shadow DOM

While the Web Component we’ve built above works, it’s not immune to outside interference, and CSS or JavaScript could modify it. Similarly, the styles you define for your component could leak out and affect others.

The Shadow DOM solves this encapsulation problem by attaching a separated DOM to the Web Component with:

The mode can either be:

  • “open” — JavaScript in the outer page can access the Shadow DOM (using Element.shadowRoot ), or
  • “closed” — the Shadow DOM can only be accessed within the Web Component.

The Shadow DOM can be manipulated like any other DOM element:

The component now renders the “Hello” text inside a <p> element and styles it. It cannot be modified by JavaScript or CSS outside the component, although some styles such as the font and color are inherited from the page because they were not explicitly defined.

The styles scoped to this Web Component cannot affect other paragraphs on the page or even other <hello-world> components.

Note that the CSS :host selector can style the outer <hello-world> element from within the Web Component:

You can also set styles to be applied when the element uses a specific class, e.g. <hello-world class="rotate90"> :

HTML Templates

Defining HTML inside a script can become impractical for more complex Web Components. A template allows you to define a chunk of HTML in your page that your Web Component can use. This has several benefits:

  • You can tweak HTML code without having to rewrite strings inside your JavaScript.
  • Components can be customized without having to create separate JavaScript classes for each type.
  • It’s easier to define HTML in HTML — and it can be modified on the server or client before the component renders.

Templates are defined in a <template> tag, and it’s practical to assign an ID so you can reference it within the component class. This example three paragraphs to display the “Hello” message:

The Web Component class can access this template, get its content, and clone the elements to ensure you’re creating a unique DOM fragment everywhere it’s used:

The DOM can be modified and added directly to the Shadow DOM:

Template Slots

Slots allow you to customize a template. Presume you wanted to use your <hello-world> Web Component but place the message within a <h1> heading in the Shadow DOM. You could write this code:

(Note the slot attribute.)

You could optionally want to add other elements such as another paragraph:

Slots can now be implemented within your template:

An element slot attribute set to “msgtext” (the <h1> ) is inserted at the point where there’s a <slot> named “msgtext.” The <p> does not have a slot name assigned, but it is used in the next available unnamed <slot> . In effect, the template becomes:

It’s not quite this simple in reality. A <slot> element in the Shadow DOM points to the inserted elements. You can only access them by locating a <slot> then using the .assignedNodes() method to return an array of inner children. The updated connectedCallback() method:

In addition, you cannot directly style the inserted elements, although you can target specific slots within your Web Component:

Template slots are a little unusual, but one benefit is that your content will be shown if JavaScript fails to run. This code shows a default heading and paragraph that are only replaced when the Web Component class successfully executes:

Therefore, you could implement some form of progressive enhancement — even if it’s just a “You need JavaScript” message!

The Declarative Shadow DOM

The examples above construct a Shadow DOM using JavaScript. That remains the only option, but an experimental declarative Shadow DOM is being developed for Chrome . This allows Server-Side Rendering and avoids any layout shifts or flashes of unstyled content.

The following code is detected by the HTML parser, which creates an identical Shadow DOM to the one you created in the last section (you’d need to update the message as necessary):

The feature is not available in any browser, and there’s no guarantee it’ll reach Firefox or Safari. You can find out more about the declarative Shadow DOM , and a polyfill is simple, but be aware that the implementation could change.

Shadow DOM Events

Your Web Component can attach events to any element in the Shadow DOM just like you would in the page DOM, such as to listen for click events on all inner children:

Unless you stopPropagation , the event will bubble up into the page DOM, but the event will be retargeted. Hence, it appears to come from your custom element rather than elements within it.

Using Web Components in Other Frameworks

Any Web Component you create will work in all JavaScript frameworks . None of them know or care about HTML elements — your <hello-world> component will be treated identically to a <div> and placed into the DOM where the class will activate.

custom-elements-everywhere.com provides a list of frameworks and Web Component notes. Most are fully compatible, although React.js has some challenges. It’s possible to use <hello-world> in JSX:

  • React can only pass primitive data types to HTML attributes (not arrays or objects)
  • React cannot listen for Web Component events, so you must manually attach your own handlers.

Web Component Criticisms and Issues

Web Components have improved significantly, but some aspects can be tricky to manage.

Styling Difficulties

Styling Web Components poses some challenges, especially if you want to override scoped styles. There are many solutions:

  • Avoid using the Shadow DOM. You could append content directly to your custom element, although any other JavaScript could accidentally or maliciously change it.
  • Use the :host classes. As we saw above, scoped CSS can apply specific styles when a class is applied to the custom element.
  • Check out CSS custom properties (variables). Custom properties cascade into Web Components so, if your element uses var(--my-color) , you can set --my-color in an outer container (such as :root ), and it’ll be used.
  • Take advantage of shadow parts. The new ::part() selector can style an inner component that has a part attribute, i.e. <h1 part="heading"> inside a <hello-world> component can be styled with the selector hello-world::part(heading) .
  • Pass in a string of styles. You can pass them as an attribute to apply within a <style> block.

None is ideal, and you’ll need to plan how other users can customize your Web Component carefully.

Ignored Inputs

Any <input> , <textarea> , or <select> fields in your Shadow DOM are not automatically associated within the containing form. Early Web Component adopters would add hidden fields to the page DOM or use the FormData interface to update values. Neither are particularly practical and break Web Component encapsulation.

The new ElementInternals interface allows a Web Component to hook into forms so custom values and validity can be defined. It’s implemented in Chrome, but a polyfill is available for other browsers.

To demonstrate, you’ll create a basic <input-age name="your-age"></input-age> component. The class must have a static formAssociated value set true and, optionally, a formAssociatedCallback() method can be called when the outer form is associated:

The constructor must now run the attachInternals() method, which allows the component to communicate with the form and other JavaScript code which wants to inspect the value or validation:

The ElementInternal’s setFormValue() method sets the element’s value for the parent form initialized with an empty string here (it can also be passed a FormData object with multiple name/value pairs). Other properties and methods include:

  • form : the parent form
  • labels : an array of elements that label the component
  • Constraint Validation API options such as willValidate, checkValidity, and validationMessage

The connectedCallback() method creates a Shadow DOM as before, but must also monitor the field for changes, so setFormValue() can be run:

You can now create an HTML form using this Web Component which acts in a similar way to other form fields:

It works, but it admittedly feels a little convoluted.

Check it out in the CodePen demonstration

For more information, refer to this article on more capable form controls .

Web Components have struggled to gain agreement and adoption at a time when JavaScript frameworks have grown in stature and capability. If you’re coming from React, Vue.js , or Angular , Web Components can look complex and clunky, especially when you’re missing features such as data-binding and state management.

There are kinks to iron out, but the future for Web Components is bright. They’re framework-agnostic, lightweight, fast, and can implement functionality that would be impossible in JavaScript alone.

A decade ago, few would have tackled a site without jQuery , but browser vendors took the excellent parts and added native alternatives (such as querySelector). The same will happen for JavaScript frameworks, and Web Components is that first tentative step.

Do you have any questions about how to use Web Components? Let’s talk about it in the comments section!

web components presentation

Freelance UK web developer, writer, and speaker. Has been around a long time and rants about standards and performance.

Related Articles and Topics

web components presentation

PHP vs JavaScript: An In-Depth Comparison of the Two Scripting Languages

web components presentation

10 Free HTML Editors on the Market for Developers and Advanced Users

  • Web Development
  • Website Performance
  • Local Development

Gravatar for this comment's author

Please educate people that

“const shadow = this.attachShadow({ mode: ‘closed’ });“

is bad code, because “attachShadow“ SETS AND RETURNS this.shadowRoot

Leave a Reply Cancel reply

By submitting this form: You agree to the processing of the submitted personal data in accordance with Kinsta's Privacy Policy , including the transfer of data to the United States.

You also agree to receive information from Kinsta related to our services, events, and promotions. You may unsubscribe at any time by following the instructions in the communications received.

  • Skip to main content
  • Skip to search
  • Skip to select language
  • Sign up for free
  • English (US)

Web Components

Baseline widely available.

This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020 .

  • See full compatibility
  • Report feedback

Web Components is a suite of different technologies allowing you to create reusable custom elements — with their functionality encapsulated away from the rest of your code — and utilize them in your web apps.

Concepts and usage

As developers, we all know that reusing code as much as possible is a good idea. This has traditionally not been so easy for custom markup structures — think of the complex HTML (and associated style and script) you've sometimes had to write to render custom UI controls, and how using them multiple times can turn your page into a mess if you are not careful.

Web Components aims to solve such problems — it consists of three main technologies, which can be used together to create versatile custom elements with encapsulated functionality that can be reused wherever you like without fear of code collisions.

A set of JavaScript APIs that allow you to define custom elements and their behavior, which can then be used as desired in your user interface.

A set of JavaScript APIs for attaching an encapsulated "shadow" DOM tree to an element — which is rendered separately from the main document DOM — and controlling associated functionality. In this way, you can keep an element's features private, so they can be scripted and styled without the fear of collision with other parts of the document.

The <template> and <slot> elements enable you to write markup templates that are not displayed in the rendered page. These can then be reused multiple times as the basis of a custom element's structure.

The basic approach for implementing a web component generally looks something like this:

  • Create a class in which you specify your web component functionality, using the class syntax.
  • Register your new custom element using the CustomElementRegistry.define() method, passing it the element name to be defined, the class or function in which its functionality is specified, and optionally, what element it inherits from.
  • If required, attach a shadow DOM to the custom element using Element.attachShadow() method. Add child elements, event listeners, etc., to the shadow DOM using regular DOM methods.
  • If required, define an HTML template using <template> and <slot> . Again use regular DOM methods to clone the template and attach it to your shadow DOM.
  • Use your custom element wherever you like on your page, just like you would any regular HTML element.

A guide showing how to use the features of custom elements to create simple web components, as well as looking into lifecycle callbacks and some other more advanced features.

A guide that looks at shadow DOM fundamentals, showing how to attach a shadow DOM to an element, add to the shadow DOM tree, style it, and more.

A guide showing how to define a reusable HTML structure using <template> and <slot> elements, and then use that structure inside your web components.

Custom elements

Contains functionality related to custom elements, most notably the CustomElementRegistry.define() method used to register new custom elements so they can then be used in your document.

Returns a reference to the CustomElementRegistry object.

Special callback functions defined inside the custom element's class definition, which affect its behavior:

Invoked when the custom element is first connected to the document's DOM.

Invoked when the custom element is disconnected from the document's DOM.

Invoked when the custom element is moved to a new document.

Invoked when one of the custom element's attributes is added, removed, or changed.

The following extensions are defined:

Allows you to specify that a standard HTML element should behave like a registered custom built-in element.

Allows you to create an instance of a standard HTML element that behaves like a given registered custom built-in element.

Pseudo-classes relating specifically to custom elements:

Matches any element that is defined, including built in elements and custom elements defined with CustomElementRegistry.define() .

Selects the shadow host of the shadow DOM containing the CSS it is used inside.

Selects the shadow host of the shadow DOM containing the CSS it is used inside (so you can select a custom element from inside its shadow DOM) — but only if the selector given as the function's parameter matches the shadow host.

Selects the shadow host of the shadow DOM containing the CSS it is used inside (so you can select a custom element from inside its shadow DOM) — but only if the selector given as the function's parameter matches the shadow host's ancestor(s) in the place it sits inside the DOM hierarchy.

Matches custom elements that are in a specified custom state. More precisely, it matches anonymous custom elements where the specified state is present in the element's CustomStateSet .

Pseudo-elements relating specifically to custom elements:

Represents any element within a shadow tree that has a matching part attribute.

Represents the root node of a shadow DOM subtree.

Extensions to the Element interface related to shadow DOM:

  • The Element.attachShadow() method attaches a shadow DOM tree to the specified element.
  • The Element.shadowRoot property returns the shadow root attached to the specified element, or null if there is no shadow root attached.

Additions to the Node interface relevant to shadow DOM:

  • The Node.getRootNode() method returns the context object's root, which optionally includes the shadow root if it is available.
  • The Node.isConnected property returns a boolean indicating whether or not the Node is connected (directly or indirectly) to the context object, e.g. the Document object in the case of the normal DOM, or the ShadowRoot in the case of a shadow DOM.

Extensions to the Event interface related to shadow DOM:

Returns true if the event will propagate across the shadow DOM boundary into the standard DOM, otherwise false .

Returns the event's path (objects on which listeners will be invoked). This does not include nodes in shadow trees if the shadow root was created with ShadowRoot.mode closed.

HTML templates

Contains an HTML fragment that is not rendered when a containing document is initially loaded, but can be displayed at runtime using JavaScript, mainly used as the basis of custom element structures. The associated DOM interface is HTMLTemplateElement .

A placeholder inside a web component that you can fill with your own markup, which lets you create separate DOM trees and present them together. The associated DOM interface is HTMLSlotElement .

Assigns a slot in a shadow DOM shadow tree to an element.

A read-only attribute which returns a reference to the <slot> in which this element is inserted.

A read-only attribute which returns a reference to the <slot> in which this text node is inserted.

Extensions to the Element interface related to slots:

Returns the name of the shadow DOM slot attached to the element.

Pseudo-elements relating specifically to slots:

Matches any content that is inserted into a slot.

Fired on an HTMLSlotElement instance ( <slot> element) when the node(s) contained in that slot change.

We are building up a number of examples in our web-components-examples GitHub repo. More will be added as time goes on.

Specifications

Browser compatibility, html.elements.template.

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

api.ShadowRoot

Photo by NeONBRAND on Unsplash

Slides - Web Components - January 2020

ARCHIVED: Latest slides available here

Let's start the year with an updated version of our slides for Web Components. You will find some new interesting links and novelties in the Web Component world!

Get your copy of the slides .

How to Build Your First Web Component

In 2023, browser support for web components (also known as custom elements) is really good. There's never been a better time to start building your own custom elements.

Web components, also known as custom elements, are new HTML elements that you create. These elements encapsulate some markup, style, and interactivity.

In this article, you'll learn the basics of web components and create a very simple web component that shows the current date.

This guide is intended as a gentle introduction to the concept, so it won't cover some more advanced aspects such as templates, slots, or shadow DOM. But, these are all powerful building blocks to building components that you should learn as you ramp up your skills.

What is a Web Component?

A web component is a custom HTML element that you define, with its own tag name. Think of it as an encapsulated, reusable piece of code. Just like regular HTML elements, web components can accept attributes and you can listen for events.

Web components are a nice way to add some extra functionality to your web app. Since it's a web standard, there's no extra third-party code needed.

A web component can be as simple or complex as you want: it can simply display some text (as the example in this article will be doing), or it can be highly interactive.

Web Component Basics

To define a web component, create a class that extends from HTMLElement . This class will contain all of your web component's behavior. After that, you need to register it with the browser by calling customElements.define .

Once you've done this, you can use your component by just adding a <my-component> element to your HTML. That's it! You've just added a web component to your page.

Note that the component name has a hyphen. This is required by the specification, to prevent name clashes with potential future standard HTML elements.

Lifecycle callbacks

Web components have a few lifecycle callbacks. These are functions that the browser calls at different parts of the component's lifecycle. Some of these callbacks are:

  • connectedCallback : Called when the element is first added to the DOM
  • disconnectedCallback : Called when the element is removed from the DOM
  • attributeChangedCallback : Called when one of the element's watched attributes change. For an attribute to be watched, you must add it to the component class's static observedAttributes property.

For this simple component, you'll only need the connectedCallback .

How to Create the Component

In a new JavaScript file, create the component class and add the call to customElements.define as shown above. Here's the first pass at the CurrentDate component:

In the connectedCallback , you are getting the current date and calling toLocaleDateString , which formats the date portion of the Date object in a more human friendly format. For example, in the en-US locale, this would be a format like 10/18/2023 .

There are no event listeners to clean up here, so there is no need for a disconnectedCallback .

Since CurrentDate extends from HTMLElement , it includes all of its properties and methods. This is why you can use the textContent property like with any other HTML element. This will set the formatted date as the value of a text node inside the <current-date> element.

How to Use the Component

Before you use the component, you need to load it using an import statement or a script tag. Here's a simple usage example using a script tag:

Note that custom elements, even when they have no child content, cannot use the self-closing tag syntax supported by some elements. They must always have an explicit closing tag.

Future Enhancements

Here are some ways you can enhance the CurrentDate component:

  • Use Intl.DateTimeFormat to create a more human-readable format for the date. You could even add attributes to customize the date format used.
  • Add support for a date attribute and adapt the component so that it can display any arbitrary date, not just the current date. Of course, in this case, you'll want to change the name from CurrentDate to something else like FormattedDate .
  • Use the HTML time element inside the component to produce more semantic markup

In this article, you took your first step into the world of web components.

Web components have no third party dependencies, so using them won't have a big impact on your bundle size. But for more complex components, you may want to reach for a library like Svelte or Lit.

Read more posts .

If you read this far, thank the author to show them you care. Say Thanks

Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started

Breaking News! The brand-new course CSS Nouveau is now available! This is the first release in the THE SPICY WEB Courses Series. Go take a look around and sign up today!

Enhance vs. Lit vs. WebC…or, How to Server-Render a Web Component

The era of custom elements SSR is upon us. Let's take a look at how to spin up a simple Node server and use custom elements as templates in three popular formats, and what this means for the future of web components.

web components presentation

One thing I’d like to get off my chest right away.

It was always possible to render custom elements on the server. Any server.

Setting any “web component-y JavaScript-y” bits aside, you could always output something like this directly in your HTML :

And then you could style all of those custom elements however you like:

Look Ma! Custom elements! Rendered by a server! JavaScript totally optional! 😲

OK OK, I know what you’re thinking. I’m leaving out some key details…

Component-Centric View Architecture and Shadow DOM #

What people usually mean when they ask if they can SSR their web components is this: hey, can I take the code I’ve already written for client-side web components using all of the web component APIs (especially shadow DOM), and basically take an on-the-fly snapshot of that render tree and stick it in my output HTML (whether for a static site or a dynamic server)?

And so we’ve seen various projects, most notably Lit, tackle this very problem and provide a mechanism to render web components on the server, with an optional hydration step on the client to take those server-rendered components and make them interactive after initial load.

Yet, this sort of “isomorphic” architecture where client and server code is essentially identical has increasingly fallen out of step with what many developers actually want. Components which only run on the server are making a big splash across a variety of ecosystems, with even React/Next.js getting in on the action .

I like using the term “ split components ” which I first heard about from the Marko project . A split component essentially divides each component into two: a server-only portion, and a client-only portion. Sometimes you can pull some or all of the server logic over to the client as well for full isomorphism, but oftentimes you simply don’t need to.

I’m going to make a bold statement to kick off our explorations of web component SSR’ing today:

The future of web components is split components .

Or to put it another way, the future of web components is HTML-first, server-first—a mantra I’ve been preaching for a long time.

But this means we have a lot to do. The web components spec historically has been pretty squarely focused on client-side APIs which potentially make the most sense in a world of client-driven app architecture, namely SPAs . It pains me that as many frameworks are deep in the throes of migrating away from SPA-as-default across our industry— thank god! —web components feel behind the times. But there are promising signs ahead.

Declarative Shadow DOM lets us server-render the internals—the guts if you will—of web components and ship those directly to the browser. Yes, Firefox still needs a simple polyfill ( 2024 update: not any longer! DSD is supported by Firefox! ) which is really no biggie, and for Chrome and Safari you can display your server-rendered components including shadow DOM with zero JavaScript . Pretty darn cool.

Furthermore, there are ongoing efforts to spec other parts of the web component APIs for a world of declarative markup. In the future we might gain declarative custom element registration and declarative ElementInternals functionality and even declarative reactive templates using DOM parts. People who work on this stuff at the spec and browser implementation level now understand the gravity of the situation. If a major API is only available to client-side JavaScript, it’s less likely to work well in an HTML-first, server-first landscape.

But…we’re not here to dream about the future. We’re here to see what we can do right here, right now . And so on with the show!

There’s Node Business Like Sh(ad)ow Business #

I’m going to demonstrate three different component formats which you can use today in any Node project inside of any potential template rendering environment. These are:

Of the two, Enhance and WebC are closer in terms of general concept. Both start with a “0kb JS” mindset and use terminology of “expansion”—aka, your top-level HTML templates include custom element tags, which then are “expanded” with the full rendered components…and those components might expand other components, and so on and so forth.

Lit’s certainly a bit different and, as a popular library for web component authors, is a well-known quantity. Like I said, Lit is typically used for “isomorphic” components (aka the code you SSR and the code you load client-side is virtually identical). However, there’s actually no hard-and-fast reason you have to do it this way. And so I demonstrate that Lit too could be used to author “split components”—although you’re fairly “on your own” in term of practical applications of it.

Starting in alphabetical order, let’s first look at Enhance.

Region 3. Move Down 5. Zoom In 300%. Enhance! #

Enhance made a splash a while back as a fullstack framework you can use to build entire web applications, all centered around the concept of server-rendering custom elements. What’s particularly nice about how Enhance is architected is that the piece which deals directly with component SSR is a standalone library anyone can grab off the shelf and use.

Here’s an example of an Enhance component:

And here’s a (simplified) example of rendering it in a main server process:

You can look at the full example code in the repo link above.

What I like about this is its conceptual simplicity. There’s not a lot you need to learn. If you know the basics of HTML, CSS, JavaScript, and Node, you can use this to DIY your own web framework.

Enhance also provides some nice style scoping features right out of the box. By default, Enhance components do not use shadow DOM. You can certainly opt-into it though, but if you don’t, you can still use some of the same nomenclature in your component styles like :host , and all of the selectors will end up prefixed with the tag name automatically. In other words:

  • :host becomes my-element
  • p becomes my-element p
  • .cls becomes my-element .cls

and so on. Neat-o!

Because Enhance components are server-only components from the start, the way you add your client-side web component code is simply by adding a script tag to your component template. So for example, I have an s-dom.js Enhance component which uses a combination of Declarative Shadow DOM and “light DOM” content, which is fantastic, and my client component is simply embedded at the bottom of the template like so:

Enhance is smart enough to collect all of the scripts in the entire render tree and include them only once at the bottom of <body> . (And components styles are also collected and included in <head> .)

While there’s much to recommend here, there are also some things I don’t like about Enhance which I’ll cover shortly. I also had to patch Enhance so that I could get at its rendered <head> content separately from the <body> content. I think Enhance is used to the idea it’s always rendering an entire HTML page template. I filed an issue on GitHub , so we’ll see if this is a use case they’d like to support going forward.

This Component is Lit. Lit AF. #

Yes, it’s mandatory to engage in juvenile humor when talking about Lit . Listen, I don’t make the rules!

So for our Lit example, things are a wee bit different than Enhance. Lit always defaults to using shadow DOM, and while you can switch it off, stuff sort of breaks because slotted content is no longer a thing (and scoped styles are more of a pain). So I just left it all as is. I’m a huge shadow DOM fan so that doesn’t bother me, but for folks who have an aversion to it or it doesn’t play well with the rest of their HTML/CSS architecture, it might prove a hurdle.

Here’s a component in Lit, similar to the first Enhance example:

Pretty standard fare if you’re used to the Lit API. The question is, how easily can you server-render this component? Well, you be the judge:

In a streaming scenario, they recommend working with RenderResultReadable so the output response can flush at various intervals to the browser, but in simpler contexts this seems to work just fine.

The split component mechanism is a bit wonky, but still doable. I ended up adding a separate template as a static property of the component, and then including that in a separate render of JS assets:

So…this is doable, but it probably just makes more sense to have a separate .js file for your client component and include that as part of whatever frontend build/bundling pipeline you might have. Maybe you even adopt .server.js and .client.js conventions, and for components where you want the same one running in both places… .iso.js ? .hybrid.js ? Hmm.

(It should be noted the Enhance example doesn’t offer an isomorphic possibility, only split components. So if you think you’ll actually need to write lots of isomorphic components, Lit becomes awfully attractive…although the number of caveats you need to keep all in your head is quite daunting.)

WebC Lets You Render Components for the Web, See? #

Yeah, see? You can now render components on the server, see? Yeah!

Like Johnny Rocco , I “want more” when it comes to options for custom elements SSR, and so we arrive at our third and final demonstration which is WebC.

WebC grew out of the Eleventy project, and like Enhance you can simply spin up an Eleventy site and install the WebC plugin and you’re off to the races with a full framework (albeit mostly oriented towards static sites).

For our purposes, WebC can be used standalone without any major gotchas and the API is straightforward (although once again I must admit it took me a bit of time to stumble onto the right formula).

It’s worth explaining up front that WebC is quite different from Enhance and Lit in terms of the syntax of writing a component. WebC doesn’t use JavaScript files like the other two. WebC provides its own HTML-based SFC (Single-File Component) format which looks a lot more like Vue or Svelte. JavaScript can be embedded into component files, whether it’s code to run on the server or code to include as scripts for the client.

Here’s an example of a WebC component:

And here’s how to render it. We’ll use a page entrypoint to include the element and then render that entrypoint from our Node process:

WebC happily provides you with separate HTML, collected styles, and collected scripts which you can then include inline on your page or hand off to some other frontend process.

WebC also provides a “light DOM” scoping mechanism similar to Enhance, except that it uses hashed class names by default and you have to manually specify a human-readable class name (and then it’s a class not the actual tag name as the selector prefix). It’s fine, but I’d prefer true scoping at the element level. Certainly shadow DOM can also be used in WebC for style scoping.

Unfortunately, the interactions between WebC server-level slots and shadow DOM slots are painful , far more than in Enhance. Within your Declarative Shadow DOM template, you have to add a webc:keep attribute to maintain proper semantics in the output HTML. And for “light DOM” tags which need to preserve a slot attribute and avoid processing by WebC, you have to add something like @attributes="({ slot: 'hello'})" . Again, it really took some time to figure this all out! There’s an issue to track this if you’re curious to see if the WebC folks can come up with a simpler solution.

It also took me a beat to figure out how to process incoming component state in JavaScript (aka to join the incoming array into a string) in my component template. Providing a function in <script webc:setup> to use in the HTML portion is pretty obvious in hindsight, but I fiddled around with a lot of other approaches before stumbling across this one.

In spite of these gotchas, I really appreciate WebC’s aesthetic, from its API design to the HTML template syntax. Others may disagree, but I truly enjoy authoring HTML as HTML , and I’ll talk much more about this in a moment. (Just be aware that, like Enhance and unlike Lit, WebC doesn’t offer isomorphic components, only split components.)

Enhance vs. Lit vs. WebC: Who Wins? #

The short answer: none of them . 🤡

So here’s a thing which really annoys me about the Node ecosystem. There’s no community protocol or meta-library (that I’m aware of at least) which lets you easily render templates from any server configuration.

In Ruby, we have Tilt . Tilt lets you render templates in a wide variety of languages, both out of the box or via third-party plugins. And by way of example, I actually created my own template language a while back as an offshoot of ERB, called Serbea . Because Serbea is available through Tilt, you can render Serbea templates from any Ruby web framework easily. Adding support for Rails was mere lines of code !

Now this does break down a bit when talking about real server components. Ruby frameworks have to supply their own partial/component render methods to use with Tilt. We also have work to do here it would seem.

Nevertheless, in an ideal world, there’s be “Nilt” (Node…Interface (for) Loading Templates? Hey, that tracks!), and Enhance and Lit and WebC and a dozen other flavors of this stuff would all just plug into “Nilt” and a variety of web frameworks would know how to use “Nilt” for views and you’d be up and running in no time. Choose your flavor.

Instead…if you’re going to use Enhance you might as well use Enhance (the framework). And if you’re going to use WebC you might as well use Eleventy. And if you’re going to use Lit…well, good luck with that. There’s no “Next.js but for Lit” (yet). Maybe use Astro?

(Speaking of Astro, it also comes with a shiny-new server component format which you could use alongside custom elements. But it only works in Astro! 😭)

I think it’s vitally important we keep talking about and emphasizing the need for interop, hence the reason I wanted to write this article. And here’s where I really get on my soapbox, so buckle up folks!

The promise of web components in browsers is that you get a true write once, run anywhere API. I can write my card or my color picker or my audio player or my site header or my business dashboard once , and utilize those components anywhere. I don’t need to tear down the whole world and rebuild from scratch because I’m using Vue, no wait React, no wait Svelte, no wait Solid, no wait Qwik, no wait…

And because web component APIs use declarative HTML standards as their launching pad, in theory my web server could be anything— as it should be. Render web components from Ruby! From Python! From Java! From Elixir! From whatever the heck you and only you like!

What we truly need is a sense of server-side interop , a vision of a component format where you could squint and see how server components could be authored in one environment and ported over to another environment without too much hassle.

And that brings me to my actual clear winner in all of this. Drumroll, please! 🥁

WebC: an Enchanting Path Forward #

WebC is the only tool I’m aware of on the market today which lets you author web components as HTML from the very start. The .webc extension of a component highlights that while this isn’t pure HTML, it certainly isn’t JavaScript either. And that’s the Achilles’ heel of technologies like Enhance or Lit. It’s HTML-in-JS, CSS-in-JS…nothing but .js files as far as the eye can see.

I really hate writing HTML in JavaScript files. 😬

It’s not how the web was architected. The browser downloads HTML first— then processes any styles or scripts which are either contained inline or linked to externally. As someone with nearly 30 years of experience working on the web, I instinctively think HTML-first when I think about how to structure my page, structure my layout, structure my components. The content always comes first, then presentation, then behavior. HTML, then CSS, then JavaScript.

And past eras of tooling understood this. Most “old-school” HTML template languages start with pure HTML-as-string-data and let you sprinkle in your code bits. Heck, PHP is essentially an entire language that was built to be HTML-first! The reason you have to include <?php at the top of every PHP code file is because otherwise it’s just a text template! ( Look at this opening example in PHP’s documentation if you don’t believe me… )

The modern evolution of this concept is a component format which actually parses your HTML server-side to turn it into the server equivalent of a DOM tree, and then walks the tree searching for special attributes, directives, handlebars, etc. to apply processing. This is slower and more effort than basic string manipulation/RegEx-fu like the older template formats, but it provides opportunities for better syntax, fewer bugs and security holes, and tighter integration between the HTML markup and the underlying server programming language.

WebC takes full advantage of this concept. When you write <span @text="msg"></span> instead of something like <span><?php echo $msg; ?></span> , you’re moving from old-and-busted “inject string output here in text file” to new-hotness “when you process this dynamic attribute, swap the execution output into this node’s contents”. In other words, you’re writing a declarative template, but it’s translating that into imperative manipulations of the DOM, just like it would on the client in a component format there.

And while WebC only runs in a JavaScript server context, you could imagine applying these same concepts and using the same component format nearly unchanged elsewhere. Yeah, that’s right. Imagine, say, a “WebR” that’s a Ruby port of WebC. The above WebC example could look like this:

Here’s what’s astounding about this hypothetical example. I rewrote the script block which executes on the server as Ruby code, but the HTML template didn’t have to change . At all.

Very little would have to change when you think about it. In server-rendered applications, most logic lives elsewhere. Controllers or routes pull content from databases and handle requests, models or entities encapsulate records, and you can easily write functions or PO(X)Os (Plain Old Ruby / JavaScript / Python / etc. Objects) to mange all sorts of business logic. The view layer only has to provide a base level of smarts to take a data structure defined elsewhere and translate it into markup.

It’s only in the so-called “modern” world of SPAs where components have fast expanded like a virus to take over the bulk of application architecture. You’re fetching data from APIs and handling forms and validating data and executing business logic all from view-layer components . It’s nothing but another form of big ball of mud software architecture.

We have a real opportunity to reset expectations and reassert best practices and codebase health, and I’m very excited about this. I can easily see a future where:

  • A variety of SSR web frameworks across a variety of languages…
  • …Use something like WebC as a common server component format…
  • …And then WebC-friendly client libraries help bridge the gap between “split components” and possibly handle WebC-style templates client-side as well for true isomorphism.

This way, you don’t really need to learn the “Enhance” way or the “Lit” way or the “Astro” way or the this way or the that way to just write a freakin’ web component. 🤪

Put another way, we desperately need a common language around thinking of web components as fullstack components . Custom elements aren’t merely a way to spin up some JavaScript and attach it to a node in the browser. They form the baseplate of the view layer of your web application.

I have to say, I really do appreciate what the Enhance folks are doing. Because they too see a world of fullstack custom elements-as-view-layer and are making that a reality today in the Enhance framework. It’s good stuff.

But then again, I keep getting tripped up by the JavaScript-centric nature of it. I can never truly get onboard with a universal web component format which is unable ever to be rendered by the infinite number of other web servers out there which aren’t Node/Deno/Edge/etc. .

And so I find myself extremely enthused by WebC . I think Zach Leatherman struck gold when working on this format. And even if we end up with further permutations down the road (and admittedly it’s an area of intense experimentation for me), WebC is the technology to take seriously today.

Want to join a fabulous community of web developers learning how to use “vanilla” web specs like HTTP, HTML, CSS, JavaScript, & Web Components—plus no-nonsense libraries & tools which promote developer happiness and avoid vendor lock-in?

It’s entirely free to get started. And when you're ready for more, our courses are here to take you even deeper down the rabbit hole. Truly, vanilla has never tasted so hot.

DEV Community

DEV Community

Stephen Belovarich

Posted on May 7, 2022 • Updated on Apr 14, 2023

The State Of Web Components in 2022

While writing a book about Web Components , I found nothing in my research that described the current state of the Web Components ecosystem. In this post, I hope to clear up any misconceptions about Web Components and provide several links to resources about Web Components. I'll review the current level of adoption, the top libraries and tooling available, and the browser support for the set of specifications known as Web Components.

  • ~18% of page loads tracked by Google contain a Web Component
  • Stencil is the most downloaded library for developing Web Components
  • Custom Elements Manifest powers documentation for Storybook where Web Components became a first-class citizen in 2021
  • Several online communities about Web Components sprung up during the pandemic including this Forem instance devoted to Web Components

Web Components have been growing in popularity among web developers ever since Custom Elements v1 became available in every evergreen browser: Chrome, Safari, Firefox, and Edge. According to Google , in 2019 “> 5% of page loads use a Web Component”. Today, Chrome Platform Status reveals that ~18% of page loads tracked by Google contain a Web Component. This statistic is derived by pages that register a custom element on the CustomElementRegistry .

Libraries and Tooling

Over the years several libraries that enable Web Component development have appeared. https://webcomponents.dev tracks 61 variants of a single component coded with Web Component specifications. divriots , a company that "builds great software to empower front-end teams", analyzes bundle size and performance of several Web Component libraries and publishes the findings in a semi-annual blog post titled "All the Ways to Make a Web Component".

  • 4 variants render faster than the same component coded with Svelte
  • 5 variants have a bundle size smaller than the same component coded with Svelte
  • 54 variants coded with custom elements have a bundle-size smaller and render faster than the same component coded with React or Vue

Top Five Web Component Libraries By Downloads

The following JavaScript libraries are ranked by weekly npm downloads. These libraries either use Web Components "under the hood" or compile down to Web Components.

  • Stencil - 357,795
  • Lit - 282,068
  • FAST - 37,489
  • Lightning Web Components - 35,452
  • Solid - 26,261
  • Weekly downloads sourced from npm on June 24, 2022.

In the past year, Web Components became a first-class citizen in Storybook .

Custom Elements Manifest is "a file format that describes custom elements". The @custom-elements-manifest/analyzer package generates a JSON file that can provide rich information about Web Components. Storybook uses this tool to generate documentation of Web Components.

Browser Support

Every major browser supports custom elements according to caniuse.com , with the exception that Apple Safari doesn't support customized built-in elements. Web Components is a set of specifications that include custom elements, Shadow DOM, and HTML templates. caniuse.com uses an outdated marketing term (custom elements v1) for the specifications that allow new HTML tags to be defined, which should probably be known as "custom elements". v1 differentiates the specifications from the prototypical version of custom elements (v0) that have been deprecated since 2014. This marketing term is confusing, mostly because HTML is a living document. caniuse.com also doesn't track some specifications related to Web Components, which may confuse newcomers.

The HTML Living Standard provides documentation for custom elements, including the three main types: autonomous, customized built-in, and form-associated custom elements. Custom elements are one part of the specifications that comprise Web Components, along with Shadow DOM and HTML templates. Other specifications enhance Web Components in some way, like CSS custom properties, but are not under the umbrella of Web Components. Below each specification is described, along with the level of browser support.

Autonomous custom elements allow engineers to define custom HTML elements. Autonomous custom elements have shipped in every modern browser.

Customized built-in elements allow reuse of behaviors from existing HTML elements, which can be a boon for Accessibility in some use cases. Customized built-in elements are available in every modern browser except Apple Safari. A WebKit representative has said in the past WebKit will never support customized built-in elements . WebKit has supported autonomous custom elements and other Web Components specifications including HTML templates and Shadow DOM since 2019. Despite marketing that suggests Safari is either on par or leading in support for specifications, WebKit drags behind other browsers in terms of supporting Web Components. A polyfill exists for customized built-ins that is necessary for Apple Safari.

Form-associated custom elements enable custom elements to participate in the HTML form lifecycle. This specification allows developers to make entirely new form controls, or when inputs are embedded or Shadow DOM, overcome issues that block form controls from reporting validity and value to HTMLFormElement , while also enabling Accessibility. form-associated custom elements are available in Chrome, Edge, and Firefox Developer Edition. There is some evidence form-associated custom elements will be available in WebKit in the future. A polyfill exists for browsers that have not implemented form-associated custom elements.

Shadow DOM provides encapsulation for HTML markup and styling for custom elements. Shadow DOM is available in every modern browser.

HTML Templates is a way to cache HTML in DOM that isn't immediately rendered but can be reused for use in the document. HTML templates are available in every modern browser.

CSS custom properties , otherwise known as CSS variables, are a viable means to provide "design tokens" that cross the Shadow boundary. While not necessarily considered a Web Component specification, CSS custom properties allow engineers to essentially reuse styling in custom elements that employ Shadow DOM. CSS custom properties are found in every modern browser.

CSS Shadow Parts allow shadow hosts to "selectively expose chosen elements from their shadow tree to the outside page for styling purposes." CSS Shadow Parts are useful for theming or other style customizations in custom elements that use Shadow DOM. CSS Shadow Parts are in every modern browser.

Specification Proposals

Web Components are a set of browser specifications. Spec is introduced over time: proposed, iteration upon, developed, and integrated into browsers. Web Components specifications are maintained and proposed in several places. An index is found on Web Incubator CG Github repository README.md .

Various specifications are in some stage of the proposal process that impacts Web Components. Those specifications are described below.

Declarative Shadow DOM

In early 2020, an explainer for Declarative Shadow DOM was introduced, a specification that enables Shadow DOM to be declared in an HTML template, rather than imperatively in a JavaScript class definition. Declarative Shadow DOM enables the server-side rendering of custom elements. Since then, Google Chrome and Microsoft Edge have implemented Declarative Shadow DOM. A ponyfill is required for the specification in Mozilla Firefox and Apple Safari.

In Mozilla's vision for the evolution of the web , the foundation sees "room for improving or adding primitives that provide declarative alternatives for situations that currently require JavaScript". This indicates Mozilla is likely to implement specifications such as Declarative Shadow DOM, as do comments like this one , although Mozilla has been critical of the specification in the past. WebKit has not signaled support for Declarative Shadow DOM. Progress on Declarative Shadow DOM can be tracked here and here .

It is worth noting that Lit has moved forward with providing a package named @lit-labs/ssr that server-side renders custom elements and makes heavy use of Declarative Shadow DOM.

Constructable Stylesheets

In 2018, an explainer was introduced for Constructable Stylesheets . Constructable Stylesheets allow users to compose CSS styles programmatically without the need for a <style> tag. This promotes the reuse of CSS styles, helping to solve a problem common in UI library development where the same CSS is repeated throughout the codebase. Constructable Stylesheets operate across shadow boundaries, replacing the need for CSS selectors in earlier versions of Web Components specifications (/deep/, >>> and ::shadow). Constructable Stylesheets are currently available in Google Chrome and Microsoft Edge. A polyfill exists for browsers that omit the spec.

Mozilla is currently implementing Constructable Stylesheets for Mozilla Firefox. WebKit has not signaled support for the specification.

HTML Template Instantiation

HTML Template Instantiation was proposed by Apple in 2017. HTML Template Instantiation would allow HTML templates to instantiate "with some parts of it substituted, conditionally included, or repeated based on JavaScript values", similar to the syntax available in Angular, Vue, or Ember. A ponyfill exists, despite a complete lack of browser support.

Other Specifications

Web Components specifications early in the proposal process include Partial Hydration , Pending Task Protocol , and Context Protocol .

For further reading about upcoming specifications, read the Web Components Community Group 2021 Spec / API Status Document .

Despite a global pandemic, the growing popularity of Web Components has spurred a community surrounding Web Components to start forming.

The Web Components Community Group aids with "collaboration between people working on web components libraries, tools, documentation, and standards". This group helps advance standards, organize conferences and meetups, and much more. A Slack organization exists for Web Components where engineers can organize.

A Forem instance devoted to Web Components became available in 2022.

This Web Components Twitter Community was formed in 2022.

Reddit has featured a Web Component community for some time.

Fullstack Web Components

Fullstack Web Components Book Cover

Are you looking to code Web Components now, but don't know where to get started? I wrote a book titled Fullstack Web Components , a hands-on guide to coding UI libraries and web applications with custom elements. In Fullstack Web Components, you'll...

  • Code several components using autonomous, customized built-in, and form-associated custom elements, Shadow DOM, HTML templates, CSS variables, and Declarative Shadow DOM
  • Develop a micro-library with TypeScript decorators that streamlines UI component development
  • Learn best practices for maintaining a UI library of Web Components with Storybook
  • Code an application using Web Components and TypeScript

Fullstack Web Components is available now at newline.co

Top comments (1)

pic

Templates let you quickly answer FAQs or store snippets for re-use.

nosherwan profile image

  • Location Australia, NSW
  • Pronouns He/Him
  • Work Full stack web apps dev
  • Joined Jun 27, 2018

Thank you, very informative. I feel that with the advent of such promising next gen frameworks such as qwik, astro, solidjs, it is imperative that we re-think they way components are made. I feel web components are the future, as they will work in a framework independent way.

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink .

Hide child comments as well

For further actions, you may consider blocking this person and/or reporting abuse

andyb1979 profile image

Best JavaScript chart customizations you should know

Andrew Bt - Mar 13

10 Compelling Reasons to Choose SciChart.js

sh20raj profile image

CORS Error Fixed - "no-cors" Mode in the Fetch API

Sh Raj - Mar 14

wangliwen profile image

How many variations can be produced by obfuscating a single line of JavaScript code: 'var a=1'?

WangLiwen - Mar 14

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Please help us make Web Components & PWA's better by completing this survey

WebComponents.org

A place to discuss and evolve web component best-practices.

The webcomponent.js polyfills enable Web Components in (evergreen) browsers that lack native support.

Install with Bower bower install webcomponentsjs

Install with npm npm install webcomponents.js

Download webcomponents.js 0.7.12 (117KB minified, 34KB gzipped)

Browser Support

Polymer

Polymer is a new type of library for the web, built on top of Web Components, and designed to leverage the evolving web platform on modern browsers.

X-Tag

X-Tag is a small JavaScript library, initially created by Mozilla & now supported by Microsoft, that brings Web Components Custom Element capabilities to all modern browsers.

Bosonic

Bosonic is a set of tools that enable you to build Web Components as the spec currently describes, and supporting not-so-modern browsers like IE9.

SkateJS

SkateJS is a superset of the web component specs, with a very small footprint, that enables you to write performant web components using a functional rendering pipeline.

CustomElements.io

CustomElements.io

A gallery to display Web Components created by the community.

Polymer Catalog

Polymer Catalog

The official product line catalog for Polymer Web Components.

Built with Polymer

Built with Polymer

A curated collection of web apps and websites using Polymer.

Custom Elements

Custom Elements

This specification describes the method for enabling the author to define and use new types of DOM elements in a document.

HTML Imports

HTML Imports

HTML Imports are a way to include and reuse HTML documents in other HTML documents.

Templates

This specification describes a method for declaring inert DOM subtrees in HTML and manipulating them to instantiate document fragments with identical contents.

Shadow DOM

This specification describes a method of establishing and maintaining functional boundaries between DOM trees and how these trees interact with each other within a document, thus enabling better functional encapsulation within the DOM.

Polymer 1.7.0 provides forward compatibility features that let you build elements that run under both 1.0 and 2.0.

Presentations

Accessibility is My Favorite Part of the Platform

My favorite part of my job is when I get to work on accessibility. I see this as removing uncertainty and anxiety from people’s day, and helping them access the information they need. But working with accessibility can be frustrating, especially when you feel like you’re fighting the platform instead of working with it.

Web Components

Article info.

  • Polymer (Library)
  • Material Design
  • CSS Modules
  • Accelerated Mobile Pages

Article Versions

  • 7 2022-02-15 11:49:34 3320,2558 7,3320 By devbot5S Migrating blockquotes to markdown syntax
  • 6 2021-05-28 04:46:37 2558,1905 6,2558 By arvindpdmn Updated browser support image.
  • 5 2020-01-06 12:34:56 1905,1065 5,1905 By arvindpdmn Updated See Also
  • 4 2018-11-28 16:36:59 1065,548 4,1065 By hemanthSK AMP expansion corrected.
  • 3 2018-06-08 08:11:42 548,547 3,548 By dineshpathak Clarification that WC is being standardized by W3C
  • Submitting ... You are editing an existing chat message. All Versions 2022-02-15 11:49:34 by devbot5S 2021-05-28 04:46:37 by arvindpdmn 2020-01-06 12:34:56 by arvindpdmn 2018-11-28 16:36:59 by hemanthSK 2018-06-08 08:11:42 by dineshpathak 2018-06-08 07:54:42 by dineshpathak 2017-04-26 13:01:50 by arvindpdmn All Sections Summary Discussion Sample Code References Milestones Tags See Also Further Reading
  • 2021-05-28 04:47:12 - By devbot5S [URL Check] The following URLs in this article are outdated. Please update. Redirected URLs: Discussion: https://www.ampproject.org/ → https://amp.dev/ Discussion: https://www.w3.org/TR/html5/scripting-1.html#the-template-element → https://html.spec.whatwg.org/multipage/scripting.html Discussion: https://www.w3.org/standards/techs/components#w3c_all → https://www.w3.org/TR/?tag=browser Further Reading: https://andrewrabon.com/the-case-for-react-like-web-components-63887335fe41?gi=75d13b69834f → https://medium.com/@andrewrabon

A webpage can be composed from modular self-contained parts. Source: Fink 2016, slide 8.

A webpage can be built in two ways: either as a monolithic unit of HTML tags or as a composition of individual parts: header, footer, menu, main body, side panel, and so on. The latter is easier to maintain due to its modular nature. Such modular design has been in common practice on the server side where pages are dynamically generated from modular views. Web Components enables this on the client side.

While the use of components is possible with frameworks or libraries such as Ember, Backbone, Angular or React, Web Components is a W3C standard. It relies on nothing more than HTML , CSS and JS . It can therefore work on all browsers, can complement and be reused across frontend frameworks. Libraries built on top of Web Components are also making development simpler.

Here's one way to define a web component,

A component is a small, potentially re-usable set of logic, behaviors and interface elements ( UI or API ).

This definition is not just about the frontend element's presentation but it's also about its behaviour. Consider a clickable button. The component for this could define the styling in terms of padding, colours and fonts. It could also define the behaviour: how the styling changes on mouse hover or mouse click; what happens when mouse is clicked. Another example is an image slider. These are usually implemented using HTML , CSS , and JavaScript, all of which can be encapsulated as a custom tag for reusability.

Web Components is being developed by W3C as a set of standards. Once fully standardized and implemented by browsers, it will change the way we design web apps.

  • Reuse : A component is made once and can be reused across different pages, apps, or frameworks.
  • Support : Once fully standardized, it will work on any browser without additional libraries.
  • Maintenance : Since the design is modular, and components are self-contained, they're easier to maintain.
  • Encapsulation : Each component on the same page can potentially have different styling. We need not worry about clashing element identities. This is due to what's called Shadow DOM .
  • Reliability : Code is not spread across HTML and JS files, thereby avoiding inconsistencies.
  • Flexibility : Components can be written inline, imported or even compiled.
  • Composability : Components can use or interface with other components.

  • Custom Elements : We can create custom HTML tags/elements and define their initialization and behaviour. These can be created using JavaScript API s. The use of ES6 Class is recommended rather than create a prototype Object.
  • HTML Templates : Tag <template> provides a markup template that can then be reused in multiple places. Templates themselves are not displayed; only their instances are displayed.
  • HTML Imports : A HTML file can import another HTML file. Thus, components defined in one file can import components defined in another file.
  • Shadow DOM : This is an encapsulated DOM tree that's separate from the main document DOM . This encapsulation ensures that the component will work regardless of the page in which it's used.

Pass data in and out only via standard interfaces to keep components interoperable. Source: Dodson 2016.

In the spirit of reuse and composability, use attributes and properties for data input. Dispatch events for output. For example, if a button is clicked, dispatch an event so that other components can take appropriate action. Don't bubble events unless they have semantics.

Use attributes to initialize. Use properties to reflect state. Every exposed attribute should have a corresponding property. Reflecting a property change to an attribute is generally not a good idea. This is because attributes are limited to string values. This means that expensive serialization and deserialization is needed to pass arrays and objects as strings via attributes. Therefore use properties instead.

Favour declarative over imperative API . For instance, avoid changing state via method calls that don't update property or dispatch events.

  • When defining custom elements, use prefixes before the hyphen to indicate a custom "namespace".
  • Custom elements that use unconventional names can be hard understand. Try to stay close to standard HTML tag names.
  • Don't raise exceptions from custom elements when for similar errors the native DOM itself would ignore and continue.
  • Configuration and state should be exposed in the logical DOM , not hidden in Shadow DOM .
  • Try to make your component self-contained without reliance on external frameworks. This makes it easy for others to reuse your component.

More best practices are given at Google Developers site with illustrative examples .

Web Components are set to change the way we build web apps but they need not replace frontend frameworks or libraries. The two can complement each other. For example, React can be used in Web Components or vice versa. Whereas React keeps DOM in sync with data, Web Components encapsulate reusable components well.

Use Shadow DOM to avoid conflict with frameworks that manage DOM updates and rendering. Also, VirtualDOM Abstraction Layer ( VAL ) gives better control over DOM along with any virtual DOM such as React or Preact.

To convert Web Components to first-class React components, react-integration can be used. Angular Elements offers custom elements but these currently have dependence on the Angular framework.

Developers who wish to develop components that can be used across any framework can look at Ionic's Stencil , SlimJS or SkakeJS . It's been said that SkateJS enables the use of React's JSX with Web Components. For data bindings, Observables and ES6 Proxies may play well with Web Components.

In passing, we mention that Accelerated Mobile Pages ( AMP ) are in fact built from Web Components and are incredibly performant.

Browser support for Web Components as on May 2021. Source: WebComponents.org 2021.

Latest status of browser support for Web Components is available on Can I Use site. Chrome and Opera offer the best support for Web Components. Browsers that don't have full native support, can use polyfills . A polyfill is a substitute implementation that a developer can use or import into a codebase until browsers natively start supporting that feature or technology. Web Components polyfills are available on GitHub .

Developers can build custom components on their own. For faster development, they can also reuse components developed and shared by others as component libraries. WebComponents.org lists 1500+ reusable elements as on June 2018. Developers can also adopt component frameworks that simplify the development process. Examples of such frameworks include Google Polymer, Mozilla X-Tag and Bosonic.

In terms of W3C standardization, <template> element is specified within the HTML 5.2 W3C Recommendation . Shadow DOM is specified in the DOM document . Web Components Current Status page summarizes the status.

Microsoft creates HTML Components (HTC) to extend the DOM with new attributes. It relies on JScript and VBScript and Microsoft ActiveX is required. In 2011, this is discontinued and deprecated on IE10.

Mozilla introduces XML Binding Language ( XBL ) . The idea is to extend default tags with custom behaviour. XBL2 comes out in 2007. While the intention is good, implementations are not. This is eventually abandoned in 2012.

From the failure of vendor-oriented approaches, comes the idea of frameworks or libraries that can offer custom elements in a cross-browser compatible manner. In 2010, AngularJS is released. Likewise, React is born in 2011 and is used internally by Facebook.

At the Fronteers 2011 conference, Alex Russell gives a talk titled "Web Components and Model Driven Views". He explains how JS frameworks are trying to do what HTML is supposed to do. He then outlines scoped CSS , custom elements and web components.

W3C publishes a working draft titled "Introduction to Web Components".

Google Chrome and Opera browsers start supporting v0 of Web Components. In 2016, the same browsers start supporting v1 of Web Components.

Sample Code

  • // Source: Chamla 2017.   /** * Here, we create a ES6 class which backs our <employee-presentation> tag, * lets call it EmployeePresentationElement (you could call it as you want !) * * It extends HTMLElement which already holds several methods and callbacks */ class EmployeePresentationElement extends HTMLElement { // We have to declare a custom constructor constructor ( ) { // First, call super() to be sure everything was made alright super ( )   // Then we can take care of our attributes const position = this . getAttribute ( 'job-position' ) const fullName = this . getAttribute ( 'full-name' ) const avatar = { service : this . getAttribute ( 'avatar-service' ) , user : this . getAttribute ( 'avatar-user' ) } const avatarUrl = `https : //avatars.io/${avatar.service}/${avatar.user}`   // Let's declare a Shadow DOM within our tag and our rendering will be done IN the Shadow DOM const shadow = this . attachShadow ( { mode : 'open' } ) ;   // Let's find our template tag and extract the content from it const template = document. querySelector ( '#employee-presentation-template' ) // In order to activate this markup, we have to import it to the document and later to append it to the shadow DOM const content = document. importNode ( template. content , true ) ;   content. querySelector ( 'h3' ) . textContent = fullName content. querySelector ( 'img' ) . src = avatarUrl content. querySelector ( 'small' ) . textContent = position   // Finaly, we can render the real DOM behind our custom tag shadow. appendChild ( content ) } }   // We have to register our custom tag to window.customElements which lists all the custom tags we have. window. customElements . define ( 'employee-presentation' , EmployeePresentationElement )  
  • < h3 > This is our employees list ! < / h3 >   <employee-presentation avatar-service = "twitter" avatar-user = "LiiorC" full- name = "Lior Chamla" job-position = "Developer" > < / employee-presentation>   <template id = "employee-presentation-template" > < style > h3 { color: navy; }   img { max-width: 150px; border-radius: 50%; box-shadow: 0px 3px 5px rgba(0,0,0, 0.5); display: block; }   < / style > < h3 >< / h3 > < img src = "" alt = "" / > < small >< / small > < / template>  
  • /* This will not affect the CSS within local scope of the template */ h3 { color : red ; }  
  • Augular Guide. 2018. "Angular Elements Overview." Angular Guide, Version 6.0.5-build.45254+sha.7031972. Accessed 2018-06-07.
  • Bailey, Derick. 2015. "Building A Component-Based Web UI With Modern JavaScript Frameworks." August 26. Accessed 2018-06-07.
  • Cagle, Kurt. 2017. "Web Components: Moving Beyond React." LinkedIn Pulse, July 20. Accessed 2018-06-07.
  • Chamla, Lior. 2017. "A brief history of WebComponents and a tutorial to make yours." Medium, August 17. Accessed 2018-06-07.
  • Cooney, Dominic, and Dimitri Glazkov, eds. 2012. "Introduction to Web Components." W3C, May 22. Accessed 2018-06-07.
  • Dodson, Rob. 2016. "Custom Elements That Work Anywhere." Medium, November 30. Accessed 2018-06-07.
  • Dodson, Rob. 2017. "Regarding the broken promise of Web Components." March 15. Accessed 2018-06-07.
  • Fink, Gil. 2016. "Web component driven development." SlideShare, November 30. Accessed 2018-06-07.
  • Fink, Gil. 2017. "Why I'm Betting on Web Components (and You Should Think About Using Them Too)." Medium, November 17. Accessed 2018-06-07.
  • Google Developers. 2017. "Web Components." Web Fundamentals, Google Developers, September 26. Accessed 2018-06-07.
  • Inkoniq. 2017. "Uncomplicate the WEB Using Web Components." Inkoniq Blog, via Medium, November 27. Accessed 2018-06-07.
  • React Docs. 2018. "Web Components." Accessed 2018-06-07.
  • Russell, Alex. 2011. "Web Components and Model Driven Views." Fronteers 2011 conference. Accessed 2018-06-07.
  • Sharp, Remy. 2010. "What is a Polyfill?" October 8. Accessed 2018-06-07.
  • The Startup Lab. 2017. "What Are Web Components?" The Startup Lab, YouTube, October 7. Accessed 2018-06-07.
  • Valeyev, Yevgeniy. 2017. "Brief history of web components." SlideShare, February 22. Accessed 2018-06-07.
  • WebComponents.org. 2014. "Web Components Best Practices." WebComponents.org, April 29. Accessed 2018-06-07.
  • WebComponents.org. 2018b. "Polyfills." WebComponents.org. Accessed 2018-06-07.
  • WebComponents.org. 2021. "Homepage." WebComponents.org. Accessed 2021-05-28.

Further Reading

  • Dodson, Rob. 2013. "A Guide to Web Components." CSS-Tricks, November 11. Updated 2014-09-09. Accessed 2018-06-07.
  • MDN Web Docs. 2018. "Web Components." MDN Web Docs, March 16. Accessed 2018-06-07.
  • Rabon, Andrew. 2018. "The Case for React-like Web Components." Medium, February 01. Accessed 2018-06-07.
  • O'Neill, Justin. 2017. "Web Components VS Frameworks." Medium, May 19. Accessed 2018-06-07.

Article Stats

Author-wise stats for article edits.

User avatar

  • Browse Articles
  • Community Outreach
  • About Devopedia
  • Author Guidelines
  • FAQ & Help
  • Forgot your password?
  • Create an account

Introduction to Web Components

W3c working draft 22 may 2012.

Copyright © 2012 W3C ® ( MIT , ERCIM , Keio ), All Rights Reserved. W3C liability , trademark and document use rules apply.

This document is a non-normative reference, which aims to provide an overview of how Web Components work. It summarizes the normative information in the respective specifications in an easy-to-digest prose and illustration.

Status of this Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document was published by the Web Applications Working Group as a First Public Working Draft. If you wish to make comments regarding this document, please send them to [email protected] ( subscribe , archives ). All feedback is welcome.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy . W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy .

Table of Contents

1 about this document, 2 introduction, 3 templates, 4.1 events in decorators, 4.2 decorators example, 5.1 presentation, 5.2 using custom elements in markup, 5.3 using custom elements in script, 5.4 element upgrade, 5.5 lifecycle methods, 5.6 extending custom elements, 5.7 error handling, 6.1 content and shadow elements, 6.2 multiple shadow subtrees, 6.3 css and shadow dom, 6.4 events in shadow dom, 6.5 making more shadows, 7 decorators vs. custom elements, 8 external custom elements and decorators, 9 isolation, confinement and encapsulation, appendix a. interfaces, appendix b. html elements, appendix c. custom element constructor properties, acknowledgements.

As mentioned earlier, this document is a work in progress. It was initially written as a thought exercise to tie up all concepts, associated with the Web components into one coherent, non-normative narrative. Then, each concept will be refined and developed into a separate normative document, subsequently feeding back changes, concepts, and terms into this document. This iterative process is still continuing today, and produced the following specifications:

  • HTML Templates

Once all information is extracted into the respective normative documents and this document is updated to accurately describe, as well as summarize the information in the normative documents, this document will be finalized and become the actual introduction for Web components.

The component model for the Web (also known as Web Components) consists of four pieces designed to be used together to let web application authors define widgets with a level of visual richness not possible with CSS alone, and ease of composition and reuse not possible with script libraries today.

These pieces are:

  • templates , which define chunks of markup that are inert but can be activated for use later;
  • decorators , which apply templates to let CSS affect rich visual and behavioral changes to documents;
  • custom elements , which let authors define their own elements, including new presentation and API, that can be used in HTML documents; and
  • shadow DOM which defines how presentation and behavior of decorators and custom elements fit together in the DOM tree.

Both decorators and custom elements are called components .

The <template> element contains markup intended to be used later—by script or some other template-aware consumer (like <decorator> and <element> elements that are described later).

The content of the <template> element is parsed by the parser, but it is inert: scripts don't run, images aren't downloaded, and so on. The <template> element is not rendered.

In script the element has one property, content , which contains the inert DOM structure, defined by the template.

For example, a Web developer may want to define the DOM structure that is created multiple times in the document, and then create an instance of it anytime it's needed.

Appending inert DOM to a document node makes it go "live", as if the DOM tree was just parsed from markup (setting innerHTML).

4 Decorators

A decorator is something that enhances or overrides the presentation of an existing element. Like all presentation aspects, the application of decorators is controlled by CSS. However, being able to specify the extra presentation using markup is unique to decorators.

The <decorator> element contains a <template> element, which specifies the markup to use for rendering the decoration.

The <content> element is the point where the content of the decorated element (element's children) should be inserted.

Decorators are applied using the decorator CSS property:

This decorator and stylesheet would cause the following markup:

To be rendered as if it was this markup (omitting user agent styles for brevity):

If the document changes so that the selector with the decorator property no longer matches—typically when a selector with the property no longer matches or the rule with this property was changed in the inline styles , the decorator is unapplied, returning the rendering of the element back to the pre-decoration state.

Even though the decorator CSS property can point to any resource on the Web, the decorator will not be applied unless its definition is loaded by this document.

The markup that generates the presentation is limited to be purely presentational: it may never run script (including inline event hanlders) and it cannot be editable .

Decorators can also attach event handlers to implement interactivity. Because the decorators are transient, it is not useful for the decorator to attach event listeners to the nodes in the template or rely on any state, since it perishes any time decorator is applied or unapplied.

Instead, decorators register event listeners with an event controller. To register an event listener with an event controller, the template includes a <script> element. The script is run once when the decorator element is parsed or inserted into the document, or loaded as part of an external document.

web components presentation

The event controller is passed to the script in the this pointer.

The call to listen means that when the button with id b is clicked, the handler h is called.

The event controller routes events originating in any of the places that the decorator is applied to the event handler.

web components presentation

When the event listener is called, the target of the event is the content that the decorator was applied to, and not content from the template. For example, given the decorator specified above, this content:

Would be rendered like this:

Clicking on the button would show a dialog containing [object HTMLSpanElement] .

This retargeting is necessary because the decorator specifies presentation; it does not affect the structure of the document. Since it is in the document, the content the decorator is applied to is the target of the event.

Similarly, if script changes the content of the template later, this doesn't have any effect on the decorator, just like setting the textContent of a <script> element doesn't cause the script to execute again.

The decorators have no way to change the state of the decorating DOM tree, other than triggering application of a different decorator.

Here is an example of how decorators could be used to implement a simple variant of the details element:

This uses two decorators. One presents the details view closed; the other presents the details view open. Each decorator uses an event handler to respond to clicks by toggling the open state of the element. The content element's select attribute will be explained in detail later.

5 Custom Elements

Custom elements are new types of DOM elements that can be defined by authors.

Custom elements can define presentation aspects like decorators. Unlike a decorator, which can be applied or unapplied to a given element, the element's type is fixed. So custom elements can also define new state and behavior, which decorators can't do because of their ephemeral nature.

The element element defines a custom element. It specifies the type of element it's a refinement of using the extends attribute:

The extends attribute specifies the tag name of the kind of element this element is an extension of. Instances of the custom element will have the tag name specified here.

The name attribute specifies the name of the custom element, by which it will be referred to in markup. The naming space of the name is the same as element tag names, and to avoid collisions, the x- prefix is required for custom element value.

Different user agents interpret HTML elements differently, however all of their interpretations are guided by the semantics of HTML.

Because not all user agents support custom elements, authors should extend the HTML element that has the closest meaning to their new kind of element. For example, if they are defining a custom element that is interactive and responds to clicks by doing some action, they should extend button.

When there isn't a HTML element that is semantically close to their custom element authors should extend a semantically neutral element like span.

A custom element may optionally include a template:

If a custom element includes a template, a copy of the template content is inserted into the custom element's shadow DOM by the generated constructor. Shadow DOM is described below.

Because custom elements use existing HTML tag names— div , button , option , and so on—we need to use an attribute to specify when an author intends to use a custom element. The attribute name is is , and its value is the name of a custom element. For example:

You can instantiate a custom element from script using the standard document.createElement facility:

Also, you can specify the constructor attribute on the <element> element to explicitly add a JavaScript property for the element constructor on the window object. That constructor can then be used to create instances of the custom element:

A custom element can expose API to script by putting properties on the constructor's prototype object, in a <script> that is nested inside the <element> element:

In order to provide graceful fallback behavior, the this pointer within the <script> element points to parent HTMLElementElement instance:

Mechanically, the code inside of the <script> element when it is a child of either <element> or <decorator> elements is executed like this:

In situations where having constructors on window object is undesirable, the custom element author can use generatedConstructor property of the HTMLElementElement :

One cannot create a custom element by setting an is attribute on an existing DOM element. Doing so will result in a no-op:

As the definition of a custom element is loaded, each element with the is attribute set to the name of that custom element is upgraded to the custom element. The upgrade process should be perceptually equivalent to removal of the element from the document and its replacement by the custom element instance.

As each element is replaced, a non-bubbling, non-cancellable event is dispatched to the element that has been removed. Scripts that want to delay interacting with part of a document until the custom elements are present can listen to this event:

Authors who want to avoid the flash of unstyled content can use CSS to change the presentation of the ordinary element until the custom element is loaded.

A custom element can optionally subscribe to these four lifecycle callbacks:

  • created —called by the generated constructor, passing a ShadowRoot instance, created from the <template> element or null , if there was no <template> element in the declaration.
  • attributeChanged —called whenever an attribute of the element is changed. The arguments are the name, old value and the new value.
  • inserted —called after the custom element is inserted into the tree. If a custom element needs to start loading resources or start timers, it can do that in this method.
  • removed —called after the custom element is removed from the tree. A custom element can stop timers that it does not need when it is not in the tree.

The callbacks are invoked with this as the instance element.

The inserted and removed callbacks may be called multiple times if the element as the element is inserted and removed from the tree.

You can subscribe to these callbacks by invoking HTMLElementElement.lifecycle method:

In addition to HTML elements, you can also extend a custom element by specifying the custom element's name as the value of the extends attribute in the <element> element:

There are several opportunities for error when setting up custom elements:

  • The tag name of the element does not match the value of the extends attribute of the custom element, eg. <div is="x-fancybutton"> , but <element name="x-fancybutton" extends="button"> . In this case, the is attribute is thrown away while parsing.
  • The value of the is attribute does not correspond to any currently defined element. This situation is treated as if the definitions hasn't been loaded yet, and the element will be upgraded as soon as the definition arrives.
  • The value of the extends attribute does not correspond to any currently defined element. In this case, the element's definition is put on hold as if it hasn't loaded, until the element mentioned in the extends attribute is loaded.
  • The value of the is attribute does not begin with an x- . This is resolved by dropping the is attribute altogether.
  • The value of the name attribute does not begin with an x- . The definition is considered invalid and is ignored.

6 Shadow DOM

Shadow DOM is a tree of DOM nodes. Shadow DOM can be applied to a custom element declaratively, by including a template, or to any element imperatively using JavaScript.

When an element has shadow DOM, the element's children are not rendered; the content of the shadow DOM is rendered instead.

Any shadow DOM subtree can specify insertion points for element's children by using a <content> element:

The <content> element acts as an insertion point for rendering only—it does not change where the elements appear in DOM. When rendering, the element's children just appear in place of the <content> element. And yes, you can have more than one <content> in the shadow DOM subtree ! The select attribute gives you a handy way to choose which children appear at which insertion point . If there is more than one <content> element, the tree order dictates when each of these elements takes a pass at selecting the children. Once the child is selected to be rendered at one insertion point , it can't be claimed by another one.

Any element can have more than one shadow DOM subtree . Don't look so puzzled! Suppose you are extending a DOM element that already has a shadow DOM subtree . What happens to that poor old tree? We could just ditch it for the new arboreal hotness, but what if you don't want to? What if you want reuse it?

For this noble purpose, we have a special <shadow> element, which acts as an insertion point for the, you guessed it, the previously applied shadow DOM subtree of this element (also known as the older tree ). For instance, you can take existing range slider (that's <input type="range"> ) and extend it, adding your extra shadow schmutz to it:

Since an element can have multiple shadows, we need to understand how these shadows interact with each other and what effect these interactions have on rendering of the element's children.

First, the order in which the shadow DOM subtrees are applied is important. Because you cannot remove a shadow DOM, the order is typically like this:

  • element shadow DOM (I got here first, nyah!)
  • shadow DOM of the element sub-class
  • shadow DOM of the element sub-sub-class
  • some shadow DOM added using script
  • decorator shadow (applied and removed with CSS rules—not technically a shadow DOM, but can, too, have <content> and <shadow> elements)

Next, we take this stack of shadow DOM subtrees and traverse it backwards, starting with the last-applied (or youngest ) subtree. Each <content> instance, encountered in tree order, grabs the element's children that it needs as usual.

This is where things get interesting. Once we're done shuffling the children into their right places to render, we check and see if we have a <shadow> element. If we don't, we're done.

If we do, we plop the next shadow subtree in our list in place of the <shadow> element, and rinse-repeat first replacing <content> insertion points , then <shadow> until we reach the start of the list.

And then—ta-da!—we have our wondrous shadow DOM Yggdrasil, ready for rendering.

Here's an easy way to remember how this works:

  • The most recently applied shadow DOM subtree has the best shot of getting fresh children for its <content> insertion points (unfair, I know!)
  • Once it's had its way, the next most recent shadow DOM subtree —if even allowed to—can rummage through the remaining children.
  • Cycle repeats until either the current shadow DOM subtree has no <shadow> element, or we've processed the oldest DOM subtree for this element.

When building a custom element, you often want to prevent document styles from interfering with what you've painstakingly crafted.

Lucky for you, the shadow DOM subtree is surrounded by an invisible boundary , only letting the user agent styles apply by default. The inheritance still works as usual—more on that later.

You can relax this boundary with the apply-author-styles attribute on the <template> element. With the attribute present, document's author styles start applying in the shadow DOM subtree .

Conversely, you can make the boundary even stronger by setting the reset-style-inherifance attribute on the <template> element. With the attribute present, all styles are reset to initial values at the shadow boundary . No more need for lengthy reset stylesheets! Just set the attribute and start with a clean slate.

There is a similar boundary between the <content> element and element's children, rendered in its place. The styles from the shadow DOM subtree do not apply to the element's children.

The magic boundary also prevents selectors from reaching into the shadow DOM subtree , skipping it altogether. For example, if <div id="foo"> had this shadow DOM subtree :

and a child

both div#foo>a and div#foo a will select the child (light link), not the anchor in the shadow DOM (shadow link).

If the component authors wish to allow some styling of the shadow DOM subtree by the component users, they can do so with CSS variables . The variable definitions specified on the shadow DOM host element are also resolved inside of the shadow DOM subtree .

To ensure that the elements of the shadow DOM subtree are not exposed outside of the subtree, there's a fair bit of work that happens while dispatching an event from inside of the subtree.

First, some events (like mutation and selectstart events) are just plain prevented from escaping out of the shadow DOM subtree —they are never heard from the outside.

Those events that do cross the shadow DOM boundary are retargeted —their target and relatedTarget values are modified to point to the element that hosts the shadow DOM subtree .

In some cases, like DOMFocusIn , mouseover , mouseout events have to be given extra attention: if you're moving a mouse between two elements inside of the shadow subtree, you don't want to be spamming the document with these events, since they will appear as non-sensical babbling after the retargeting (what? the element just reported that the mouse just moved from itself back to itself?!)

As implied before, you can always add a shadow DOM subtree to any DOM element in one line of code:

This does two things:

  • Creates a brand-spanking-new ShadowRoot instance, which you should imagine as this shadowy, invisible other side of your element. It's like a tiny document that lives inside of our custom element, and serves as the root of your shadow DOM subtree .
  • Sets anyElement as the host of this newly created shadow DOM subtree .

The important thing to remember is that while you can add new shadow DOM subtrees this way, you can never remove them: they just keep stacking up.

Decorator shadows are never accessible with DOM. When the decorator is created, the shadow DOM subtree is placed in a cold, dark place—for storage. Once the decorator is applied to an element, this shadow DOM subtree is used to produce the rendering, but its nodes are never accessible from script. You can, however listen to events that happen inside the decorator shadow using EventController.

An easy way to think of the decorator shadow is a projection. You can see it, but never can actually touch it.

On the other hand, the custom element shadow (or any shadow DOM subtree created using script) is a real DOM tree that you as the custom element author can change as you please.

Another important difference between the two is the fact that you can unapply a decorator. On the other hand, once you've instantiated a custom element, its qualities—including its shadow DOM subtree —are inherent part of element's identity.

Custom elements and decorators can be loaded from external files using the link tag:

Only decorator elements, element elements and script elements are interpreted by the UA. The DOM of this document is not available to script. The origin of the embedding document is used as the origin of the embedded document. Script runs as though it was async defer. The custom element definitions and decorators are not made available until the scripts have run. Documents which are retrieved cross-origin use CORs to determine that the definitions are designed to run cross-site.

Component isolation can be viewed as combination of two parts:

  • confinement , when the document wants to prevent a component from accessing document information, and
  • encapsulation , when the component wants to prevent the document from accessing inner state of the component.

Component encapsulation is partially enforced with shadow DOM, ensuring that shadow DOM nodes never appear in the event dispatch, range, focus-related DOM accessors or any APIs that query DOM nodes. It is up the author of the component to choose whether the inner state is exposed.

Component confinement is trickier, but possible using existing primitives, such as iframe or workers. The general solution would be to treat the component as the corruptible agent, which is responsible for the component user interface and interaction with the document. The component would then load a worker (or an iframe ) and communicate with it using postMessage :

Suppose we we want to display a clickable map of timezones instead of a select element. Here's how one could implement this using decorators:

You would apply this decorator as:

provided that there's the following markup in the document:

And here's the implementation using custom elements:

You would use this custom element like so:

For more examples, take a look at the Web Components Samples .

Represents an insertion point in a shadow DOM subtree . The insertion point is replaced with the elements' children at rendering time. The <content> element itself is never rendered.

Context: Where flow content is expected.

Children: anything (fallback content)

Attributes:

select —the value is a list of selector fragments , addressing immediate children of the element.

Defines a new decorator. Typically, you would also give it an id attribute to make it addressable from CSS.

Context: anywhere in the document.

Children: <template> and <script>

apply-author-styles —if true , the author styles of the document apply to the shadow DOM subtree of the element. If false (default), the author styles do not apply.

Defines a new custom element.

constructor —name of the generated constructor function. If specified, a key by this name is added to the window object, referring to the element's generated constructor.

extends —tag name of the element or a defined custom element constructor name that the new custom element extends.

name —the name of the custom element constructor that is generated by this definition.

Specifies a shadow insertion point , where the older shadow DOM subtree in element's shadow DOM tree stack is rendered. The <shadow> element itself is never rendered.

Children: anything (fallback content).

Defines an inert chunk of DOM that can then be used for creating DOM instances in an unknown parsing context.

Children: any element.

Here are some more properties of the generated constructor and FancyButton instances:

Thanks to Alex Komoroske , Alex Russell , Darin Fisher , Dirk Pranke , Divya Manian , Erik Arvidsson , Hayato Ito , Hajime Morita , Ian Hickson , Jonas Sicking , Rafael Weinstein , Roland Steiner , and Tab Atkins for their comments and contributions to this document.

Web Components Are Easier Than You Think

Avatar of John Rhea

📣 Freelancers, Developers, and Part-Time Agency Owners: Kickstart Your Own Digital Agency with UACADEMY Launch by UGURUS 📣

When I’d go to a conference (when we were able to do such things) and see someone do a presentation on web components, I always thought it was pretty nifty (yes, apparently, I’m from 1950), but it always seemed complicated and excessive. A thousand lines of JavaScript to save four lines of HTML. The speaker would inevitably either gloss over the oodles of JavaScript to get it working or they’d go into excruciating detail and my eyes would glaze over as I thought about whether my per diem covered snacks.

But in a recent reference project to make learning HTML easier (by adding zombies and silly jokes, of course), the completist in me decided I had to cover every HTML element in the spec. Beyond those conference presentations, this was my first introduction to the <slot> and <template> elements. But as I tried to write something accurate and engaging, I was forced to delve a bit deeper.

And I’ve learned something in the process: web components are a lot easier than I remember.

Article series

  • Web Components Are Easier Than You Think (You are here)
  • Interactive Web Components Are Easier Than You Think
  • Using Web Components in WordPress is Easier Than You Think
  • Supercharging Built-In Elements With Web Components “is” Easier Than You Think
  • Context-Aware Web Components Are Easier Than You Think
  • Web Component Pseudo-Classes and Pseudo-Elements are Easier Than You Think

Either web components have come a long way since the last time I caught myself daydreaming about snacks at a conference, or I let my initial fear of them get in the way of truly knowing them — probably both.

I’m here to tell you that you—yes, you —can create a web component. Let’s leave our distractions, fears, and even our snacks at the door for a moment and do this together.

Let’s start with the <template>

A <template> is an HTML element that allows us to create, well, a template—the HTML structure for the web component. A template doesn’t have to be a huge chunk of code. It can be as simple as:

The <template> element is important because it holds things together. It’s like the foundation of building; it’s the base from which everything else is built. Let’s use this small bit of HTML as the template for an <apocalyptic-warning> web component—you know, as a warning when the zombie apocalypse is upon us.

Then there’s the <slot>

<slot> is merely another HTML element just like <template> . But in this case, <slot> customizes what the <template> renders on the page.

Here, we’ve slotted (is that even a word?) the word “Zombies” in the templated markup. If we don’t do anything with the slot, it defaults to the content between the tags. That would be “Zombies” in this example.

Using <slot> is a lot like having a placeholder. We can use the placeholder as is, or define something else to go in there instead. We do that with the name attribute.

The name attribute tells the web component which content goes where in the template. Right now, we’ve got a slot called whats-coming . We’re assuming zombies are coming first in the apocalypse, but the <slot> gives us some flexibility to slot something else in, like if it ends up being a robot, werewolf, or even a web component apocalypse.

Using the component

We’re technically done “writing” the component and can drop it in anywhere we want to use it.

See what we did there? We put the <apocalyptic-warning> component on the page just like any other <div> or whatever. But we also dropped a <span> in there that references the name attribute of our <slot> . And what’s between that <span> is what we want to swap in for “Zombies” when the component renders.

Here’s a little gotcha worth calling out: custom element names must have a hyphen in them. It’s just one of those things you’ve gotta know going into things. The spec prescribes that to prevent conflicts in the event that HTML releases a new element with the same name.

Still with me so far? Not too scary, right? Well, minus the zombies. We still have a little work to do to make the <slot> swap possible, and that’s where we start to get into JavaScript.

Registering the component

As I said, you do need some JavaScript to make this all work, but it’s not the super complex, thousand-lined, in-depth code I always thought. Hopefully I can convince you as well.

You need a constructor function that registers the custom element. Otherwise, our component is like the undead: it’s there but not fully alive.

Here’s the constructor we’ll use:

I left detailed comments in there that explain things line by line. Except the last line:

We’re doing a lot in here. First, we’re taking our custom element ( this ) and creating a clandestine operative—I mean, shadow DOM. mode: open simply means that JavaScript from outside the :root can access and manipulate the elements within the shadow DOM, sort of like setting up back door access to the component.

From there, the shadow DOM has been created and we append a node to it. That node will be a deep copy of the template, including all elements and text of the template. With the template attached to the shadow DOM of the custom element, the <slot> and slot attribute take over for matching up content with where it should go.

Check this out. Now we can plop two instances of the same component, rendering different content simply by changing one element.

Styling the component

You may have noticed styling in that demo. As you might expect, we absolutely have the ability to style our component with CSS. In fact, we can include a <style> element right in the <template> .

This way, the styles are scoped directly to the component and nothing leaks out to other elements on the same page, thanks to the shadow DOM.

Now in my head, I assumed that a custom element was taking a copy of the template, inserting the content you’ve added, and then injecting that into the page using the shadow DOM. While that’s what it looks like on the front end, that’s not how it actually works in the DOM. The content in a custom element stays where it is and the shadow DOM is sort of laid on top like an overlay.

Screenshot of the HTML source of the zombie-warning component. The custom element is expanded in the shadow dam, including the style block, the custom element, and the template.

And since the content is technically outside the template, any descendant selectors or classes we use in the template’s <style> element will have no affect on the slotted content. This doesn’t allow full encapsulation the way I had hoped or expected. But since a custom element is an element, we can use it as an element selector in any ol’ CSS file, including the main stylesheet used on a page. And although the inserted material isn’t technically in the template, it is in the custom element and descendant selectors from the CSS will work.

But beware! Styles in the main CSS file cannot access elements in the <template> or shadow DOM.

Let’s put all of this together

Let’s look at an example, say a profile for a zombie dating service, like one you might need after the apocalypse. In order to style both the default content and any inserted content, we need both a <style> element in the <template> and styling in a CSS file.

The JavaScript code is exactly the same except now we’re working with a different component name, <zombie-profile> .

Here’s the HTML template, including the encapsulated CSS:

Here’s the CSS for our <zombie-profile> element and its descendants from our main CSS file. Notice the duplication in there to ensure both the replaced elements and elements from the template are styled the same.

All together now!

While there are still a few gotchas and other nuances, I hope you feel more empowered to work with the web components now than you were a few minutes ago. Dip your toes in like we have here. Maybe sprinkle a custom component into your work here and there to get a feel for it and where it makes sense.

That’s really it. Now what are you more scared of, web components or the zombie apocalypse? I might have said web components in the not-so-distant past, but now I’m proud to say that zombies are the only thing that worry me (well, that and whether my per diem will cover snacks…)

Regarding the naming of a custom element, here you can check if it is valid and not used with another framework.

https://raw.githack.com/nuxodin/web-namespace-registry/main/web/index.html

Nice. Thanks for sharing that resource!

Nice! But what about browser support?

Pretty good, actually. Not in the undead browser that is IE, but they work pretty much everywhere else. https://caniuse.com/custom-elementsv1

Regarding hyphens in custom-element names, I wouldn’t say the spec is still in flux; this part has been really stable for years and is unlikely to change. New web component specs are in the works though, like AOM, etc.

Good catch. The general spec was more the thing in flux than the hyphens, but that wasn’t clear from the context. Thanks for clarifying!

Nice article! I appreciate you taking the time to explain how web components work!

Although, by the end I found myself still wondering “Why would I use this?”

I don’t mean that in a critical way. I think you did a great job explaining it. I’m just trying to think of a real-world situation that would make sense to use it.

In the example, each had quite a bit of HTML, so it didn’t seem like we saved very much code, but it did add another layer of abstraction, and a JavaScript dependancy.

Normally, I’d expect to do something like this with PHP, and then style it with CSS. But I can’t figure out why I’d want to layer a web component on top of it.

I suppose I’m probably just missing something.

Can you think of any any simple real-world applications? I’d love to hear your thoughts.

Adding interactive elements is much easier with Web Components than writing them with just pure Vanilla JS. WCs are kinda the native version of React.

I’ve wondered that very same thing (while thinking about snacks) and I would agree PHP can handle many of the lowest level use cases. But there are a few places where I think this could shine.

  • Contexts where a server side language is unavailable or inconvenient. For instance the EPUB3 spec allows for JavaScript. Plus there are many JavaScript-only or JavaScript-mainly sites out there.

When you need to isolate CSS styles. While it’s not a perfect encapsulation as I talked about above, you can isolate quite a bit. About the only other way to do that is with iframes.

Consistency across contexts. Yes, this can be done with PHP/a server side language too, but if there are some contexts of 1 and/or you want to do 2, you can have greater consistency across those contexts.

I like to think of web components as a tool in your tool belt. It won’t solve every problem, but sometimes it’s just the right solution to your problem.

Components are much like the PHP templates you are used to. They save code only when you are using multiple instances of them on the same page or across many pages.

Most importantly, even when it doesn’t save the number of code lines, it does give you a way to split your HTML into simpler blocks, making it easier to manage and read:

Think of a 4000 line PHP file, you’d want to clean that up somehow, right? Giving names to large chunk of code (e.g. zombie-profile) makes it a lot easier to read and skip through when searching for things.

The scoped CSS is something that a lot of people are excited about. Personally, I would prefer to have a way to change the style of all my components from a global CSS, but that’s just me.

Web components are a good use case for a design system. If you are working on a bigger team and they want to use different javascript libraries in different teams, then it can be hard to have component design consistency.

You can use a web component in any framework E.g. React or Vue. So the developers just add “”. The component comes with the design built-in. You can update changes to your web components library and all teams get the new design when they load the library again from NPM or via CDN.

Hi, great article! I was inspired by your tutorial to recreate it on Observable to teach myself how to get it working. Here’s a link https://observablehq.com/@triptych/web-component-test

Thanks for this! I will start using web components more often now because of this article .

I’d say that learning Web Components it’s much easier than learning any new Framework/Library nowadays. I’ve even made a few myself.

Here is my switch-component

Very good information for app developers. These hybrid tools make it faster to develop the app for all platforms simultaneously. The features will improve slowly over some time. Still, it is a good start for developing apps faste

Thanks for the article! Very informative and entertaining :) This example could be a good use-case for css pseudo-element ::slotted(), which allows you to style the contents of the slots from inside the shadow DOM https://developer.mozilla.org/en-US/docs/Web/CSS/ ::slotted

Good find, Rose. I hadn’t seen ::slotted() before. I’d looked at ::part() but that didn’t solve the encapsulation issue. Guess I should stop daydreaming about snacks, I still have a lot to learn :)

If you have any tips on how to include with a Drupal 8 or 9 site, I would be most interested to hear. Thank you for clarifying what is otherwise a complicated topic.

I haven’t used Drupal 8 or 9 (I did use Drupal 7 a few years ago, but that skillset has atrophied). My (probably ultra naive) assumption would be that you’d include the JS/CSS just like you’d include any other JS/CSS in your theme or module. Sorry I can’t be more helpful.

Unfortunately for my org, and my others, IE is still supported.

Would love some recommendations as far as pollyfills are concerned for support there. It seems like there’s full frameworks like polymer and then a hand-full of other pollyfill libraries. Guidance would be awesome.

You poor, poor man. I haven’t used polyfills myself, but webcomponents.org has a good article on it https://www.webcomponents.org/polyfills

Nostalgic side unnecessary comment, that used to be possible in IE6 (custom elements, and htc)

It’s interesting to see people building one-off web components like this. A lot of people don’t want to learn a “framework” but I feel the real power of web components comes in the form of something larger like a design system. I create components with Stencil, which is very framework-like – and I came in with very little node.js and modern tooling background, so it was a steep learning curve. What Stencil buys you is robust polyfills for both IE11/old Edge and newer JS features. I feel completely spoiled being able to use the latest JS features (mostly) and not having to worry about compatibility because it all gets compiled down to usable and polyfilled browser JS.

Great article. It makes me all the more happier to be learning Svelte though! All the benefit of components and using vanilla JS but way easier from a development perspective.

Their new kit.svelte.dev project is especially exciting.

One thing this doesn’t address is having data object attributes to DRY things up.

While this level of encapsulation is nice:

This is better:

I haven’t found any good way to do this natively, but it appears that the Lit framework creates a thin wrapper around web components to provide these sorts of abilities. There may be other options I’m not aware of, but that’s the most promising I’ve seen.

The template part is terrible. If you are to share the component in may different pages, it should be with the JavaScript file: and you will have to use plain text for it. It is, simply terrible, at least before we have some compiler tools for it. Or, it “can” be an advantage that you can provide different template in different page but…at least you need to provide a “default” template.

web components presentation

IMAGES

  1. A Quick Guide through Custom Web Components

    web components presentation

  2. Web components: The ultimate guide

    web components presentation

  3. 10 Most Important Components of Web Development

    web components presentation

  4. Web Components

    web components presentation

  5. Uncomplicate the WEB Using Web Components

    web components presentation

  6. Web components: The ultimate guide

    web components presentation

VIDEO

  1. Introduction to The Web Development Empowerment Class

  2. 1

  3. Web Application Development Presentation

  4. MS Website Presentation

  5. About Web Component Engineering

  6. Electrical Components Presentation

COMMENTS

  1. A Complete Introduction to Web Components in 2024

    The Web Component class can access this template, get its content, and clone the elements to ensure you're creating a unique DOM fragment everywhere it's used: const template = document.getElementById('hello-world').content.cloneNode(true); The DOM can be modified and added directly to the Shadow DOM:

  2. How To Build a Web Component With Lit Elements

    First, build the docs with this command: npm run docs. Next, run the following commands in separate terminals. The first command will monitor the docs folder for changes and rebuild when files are changed. The second command will start a web server for the docs on localhost. Run the docs:gen:watch command:

  3. Slides

    Presentation slides to introduce Web Components and the State of the Art as of March 2020 ARCHIVED: Latest slides available here Latest version of our slides for Web Components.

  4. Web Components

    Web Components is a suite of different technologies allowing you to create reusable custom elements — with their functionality encapsulated away from the rest of your code — and utilize them in your web apps. Concepts and usage. As developers, we all know that reusing code as much as possible is a good idea. This has traditionally not been ...

  5. Slides

    Presentation slides to introduce Web Components and the State of the Art as of November 2020. Latest version of our slides for Web Components. You will find some new interesting links and novelties in the Web Component world! Get your copy of the slides.

  6. An Introduction to Web Components

    Web Components consist of three separate technologies that are used together: Custom Elements. Quite simply, these are fully-valid HTML elements with custom templates, behaviors and tag names (e.g. <one-dialog>) made with a set of JavaScript APIs. Custom Elements are defined in the HTML Living Standard specification. Shadow DOM.

  7. A Complete Introduction to Web Components

    Want to better understand web components and how they work? Click play to dive in ⬆️👉Subscribe: https://www.youtube.com/c/Kinsta?sub_confirmation=1We all ...

  8. Web Components v1

    Today, thanks to broad collaboration between browser vendors, the next-generation of the Web Components spec - v1 - is gaining wide support. Chrome supports the two major specs that make up Web Components - Shadow DOM and Custom Elements - as of Chrome 53 and Chrome 54 respectively. Safari shipped support for Shadow DOM v1 in Safari 10, and has ...

  9. Building components

    Custom Elements. Custom elements give developers the ability to extend HTML and create their own tags. Because custom elements are standards based they benefit from the Web's built-in component model. The result is more modular code that can be reused in many different contexts. Learn more.

  10. Slides

    Presentation slides to introduce Web Components and the State of the Art as of January 2020 ARCHIVED: Latest slides available here Let's start the year with an updated version of our slides for Web Components.

  11. How to Build Your First Web Component

    Web Component Basics. To define a web component, create a class that extends from HTMLElement. This class will contain all of your web component's behavior. After that, you need to register it with the browser by calling customElements.define. class MyComponent extends HTMLElement { // component implementation goes here }

  12. Enhance vs. Lit vs. WebC…or, How to Server-Render a Web Component

    The promise of web components in browsers is that you get a true write once, ... The content always comes first, then presentation, then behavior. HTML, then CSS, then JavaScript. And past eras of tooling understood this. Most "old-school" HTML template languages start with pure HTML-as-string-data and let you sprinkle in your code bits ...

  13. Web components: the secret ingredient helping power the web

    The web components specifications provide a low-level set of APIs that let you extend the browser's built-in set of HTML tags. Web components provide: A common method for creating a component (using standard DOM APIs). A common way of receiving and sending data (using properties/events).

  14. Testing Recipes for web components: Part 1

    So we comes to end to test our presentation web component, in next part we will go to test stateful components and most important the custom events testing. ... State Management in Web Components: Crafting Cohesive and Scalable Solutions. State management is the heartbeat of any dynamic web application, influencing its functionality ...

  15. The State Of Web Components in 2022

    Web Components are a set of browser specifications. Spec is introduced over time: proposed, iteration upon, developed, and integrated into browsers. Web Components specifications are maintained and proposed in several places. An index is found on Web Incubator CG Github repository README.md. Various specifications are in some stage of the ...

  16. WebComponents.org

    Polymer is a new type of library for the web, built on top of Web Components, and designed to leverage the evolving web platform on modern browsers. X-Tag. X-Tag is a small JavaScript library, initially created by Mozilla & now supported by Microsoft, that brings Web Components Custom Element capabilities to all modern browsers. Bosonic

  17. Web Components

    8 likes • 2,712 views. Nikolaus Graf Follow. Web Components are like Lego bricks. Easy to assemble and every piece simply fits together. But there is even more to it. Being able to create your own HTML-Tags with encapsulated style & logic changes the way you think about structuring your web applications.

  18. Web Components

    Latest status of browser support for Web Components is available on Can I Use site. Chrome and Opera offer the best support for Web Components. Browsers that don't have full native support, can use polyfills. A polyfill is a substitute implementation that a developer can use or import into a codebase until browsers natively start supporting that feature or technology.

  19. Introduction to Web Components

    2 Introduction. The component model for the Web ("Web Components") consists of five pieces: Templates, which define chunks of markup that are inert but can be activated for use later. Decorators, which apply templates based on CSS selectors to affect rich visual and behavioral changes to documents.

  20. Introduction to Web Components

    2 Introduction. The component model for the Web (also known as Web Components) consists of four pieces designed to be used together to let web application authors define widgets with a level of visual richness not possible with CSS alone, and ease of composition and reuse not possible with script libraries today.

  21. Web components

    Web components - Download as a PDF or view online for free. Web components - Download as a PDF or view online for free. Submit Search. Upload. ... Presentation of the book "Mikado Method" Jörn Dinkla ...

  22. Web Components Are Easier Than You Think

    Supercharging Built-In Elements With Web Components "is" Easier Than You Think. Context-Aware Web Components Are Easier Than You Think. Web Component Pseudo-Classes and Pseudo-Elements are Easier Than You Think. Either web components have come a long way since the last time I caught myself daydreaming about snacks at a conference, or I let ...

  23. 2023 State of Web Components

    Web Components are now even in space. The SpaceX Crew displays are running Chromium, making extensive use of Web Components. The Standards Landscape. Web Standards are ever evolving, and this includes Web Components. In the three years since v1 shipped to all major browsers, the number of features under the Web Components umbrella has nearly ...