Home Web Front-end JS Tutorial Web Components: An Introduction

Web Components: An Introduction

Jan 03, 2025 am 04:40 AM

In modern web development, frameworks are all the rage. Almost all modern frameworks have the concept of components. The idea behind components is breaking your frontend logic down into smaller reusable chunks that you can share across pages or projects. Generally these components are not reusable across other frameworks, and will require a build process for compiling them down to JavaScript that can run in the browser.

What if I told you there was a way to build components using vanilla JavaScript and widely available browser APIs that you could share across frameworks? This is now a reality with Web Components. Here we will take a quick look at the different types of Web Components, and some of the power we can wield with them.

The Basics of Web Components

Web Components are defined using the Custom Element Registry. This is an API that most modern browsers supply. To create a Web Component, you simply define it in code and then register it in the Custom Element Registry. Once it's registered and defined using the right naming conventions, the component is available for use within the page.

customElements.define("my-component", MyComponentClass);
Copy after login
Copy after login
Copy after login

Types of Web Components

Web Components can be broken down into two different categories. These are Autonomous Web Components and Custom Built-In Elements.

Autonomous Web Components are an extension of the generic HTMLElement class. These components are generally more flexible, as you are essentially building your own HTML element with the power to customize all behavior from the ground up. This includes the root element used for rendering the component. Once defined, you use Autonomous Web Components just like any other HTML element.

<my-button>



<p><strong>Custom Built-In Elements</strong> extend specific HTML elements.  For example, you may extend the HTMLButtonElement class or the HTMLAnchorElement.  These are meant to augment the functionality of existing HTML elements. To use a Custom Built-In element, you use the "is" attribute on the HTML element you are augmenting to tell it that it is an instance of the Web Component.<br>
</p>

<pre class="brush:php;toolbar:false"><button is="my-button">



<h3>
  
  
  Naming Web Components
</h3>

<p>When defining a Web Component, there are certain conventions that must be followed.  </p>

<p>Generally you will name your components similar to HTML elements with your own prefix attached to keep things simple (i.e. <my-button>).  The basic rules require that the element name start with a lowercase letter, and it must include a hyphen.  These guidelines will get you by for most cases, but I would recommend looking at the HTML spec if you're curious about all rules.<br>


<pre class="brush:php;toolbar:false"><!--Valid-->
<my-button/>
<your-button/>

<!--Invalid-->
<My-button/>
<1234-button/>
<Mybutton/>
Copy after login

Lifecycle Hooks

Web components have specific lifecycle hooks that are used for reacting to different phases that the component goes through. The hooks are the following:

  • connectedCallback -> Runs when the component is attached to the DOM.
  • disconnectedCallback -> Runs when the component is detached from the DOM.
  • adoptedCallback -> Runs each time the component is attached to a new DOM.
  • attributeChangedCallback -> Runs when an attribute from the list of "observedAttributes" updates.
class MyComponent extends HTMLElement {
    static observedAttributes = ["btntype"]
    connectedCallback() {
        // Handle when the component is attached to the DOM
    }
    disconnectedCallback() {
        // Handle when the component is removed from the DOM
    }
    adoptedCallback() {
        // Handle when the component is attached to a new DOM
    }
    attributeChangedCallback(name, oldValue, newValue) {
        // Trigged when the "btntype" attribute is changed since it is in the list of observedAttributes.
        // "name" will be the name of the attribute that changed.
        // "oldValue" is the value before the change.
        // "newValue" is the new value after the change.
    }
}
Copy after login

These lifecycle hooks are used for doing any initialization or cleanup work required when creating/destroying component instances. The attributeChangedCallback is especially useful, as it allows to react to attribute value updates. Web Components have a special static attribute called "observedAttributes", which is meant to be an array of attribute names (strings) that will trigger the attributeChangedCallback.

Accessibility

Accessibility is an important consideration in any web development done today. When it comes to web components, you use ARIA attributes just like you would in regular HTML or in a framework, but generally speaking you will inherit the built-in roles and accessibility functionality of the HTML elements you are using.

All the same guidelines apply here that would anywhere else. For example, make sure you are using semantic HTML when building your components, add any necessary keyboard handling that might be required, and make sure stuff like focus and color contrast are managed properly.

The Shadow DOM

The Shadow DOM is probably the most confusing and controversial part of Web Components. The Shadow DOM is essentially a separately scoped piece of the DOM that lives within a Web Component

The Shadow DOM is mainly a concern for Autonomous Web Components since Custom Built-In elements are just adding to existing HTML elements. For Autonomous Web Components, the custom tag representing the element (i.e. ) is considered the "host" element. Within the host element is the "shadow root". Within the shadow root is where the markup for the component is rendered.

Here is an example where you will see the the "my-button" element as the host, with the Shadow DOM inside.

Web Components: An Introduction

When building web components, there are two modes you can set the Shadow DOM to. These modes are "open" and "closed". Open Shadow DOMs can be accessed with JavaScript outside the Shadow Root in the Light DOM, while closed Shadow DOMs cannot.

customElements.define("my-component", MyComponentClass);
Copy after login
Copy after login
Copy after login

Any Styles you define within the Shadow DOM are scoped within the Shadow DOM an do not pollute the rest of the document. Any styles defined in the "Light DOM" (the rest of the document) do not penetrate the Shadow DOM (CSS variables are an exception, but we won't get into that here). Modern browsers do provide ways to target the Shadow DOM directly from the Light DOM using CSS using parts. You can add parts to the Shadow DOM of your component by adding part attributes to your markup. Those parts can then be targeted in CSS using the ::part pseudo selector. This is extremely handy, but it is pretty limited by nature. You cannot chain child selectors off the ::part selector. You can only target the specific element that has a "part" attribute within the Shadow DOM.

Accessibility is also an important consideration when working with the Shadow DOM. If you've ever worked with ARIA attributes, then you are familiar with "aria-describedby" and "aria-labelledby", which are generally given an ID that references another element containing a label or description of the content for screen readers. The Shadow DOM keeps IDs scoped separately similar to styles, so you cannot reference an ID that lives within the Shadow DOM from the Light DOM and vise versa. This can present a challenge when trying to provide detailed descriptions that you need to provide dynamically, but workarounds exist that we won't dive into in this introduction.

Templates and Slots

Templates and slots are tools that can be used in combination with the Shadow DOM to enhance web components. Templates are used for creating reusable snippets within Web Components, while slots are used for exposing "holes" that content from the Light DOM can be passed into.

Templates are handy if there is a snippet of HTML that you need to render over and over again within a Web Component. They can also be used outside Web Components, but have more limited use cases. They are implemented using the "template" tag.

Slots are used for passing content from the Light DOM into a Web Component, and are implemented using the "slot" tag. This is handy if you have a generic component that may require dynamic content to get passed in. A good example may be a generic card component, where you could have a slot exposed to pass markup into the body of the card. Slots have a "name" attribute that you can provide for uniquely identifying the slot. This is handy if you need to put multiple slots into a web component. When passing content in, you can simply pass an attribute with a value of slot="your-slot-name" and the content will get passed to the slot with the matching name.

Slots and the Shadow DOM have a unique interaction that is worth noting. Slots can have default content that renders in the event that nothing is passed in. Content passed into slots lives within the Light DOM and is "shallow copied" into the Shadow DOM. You can see this visually in the browser inspector. The slot content will render within the web component, but in the DOM, the content technically lives outside the web component and provides a link to the slot.

Web Components: An Introduction

This being said, that means all slot content is styled and referenced just like any other content within the Light DOM. Styles within the Light DOM will impact slot content, while Shadow DOM styles will not. There are APIs available for interacting with slot content from within the web component.

Web Component Support

Web Components are fairly well supported in modern browsers. The main exception is Safari, which does not support Custom Built-In Elements. If you need to support older browsers like Internet Explorer 11, you are going to have to polyfill some things.

Basic Examples

Now that we've gotten a brief introduction of all the basic concepts, let's take a look at some examples.

Autonomous Custom Elements

Here is an example autonomous custom element called "my-button":

customElements.define("my-component", MyComponentClass);
Copy after login
Copy after login
Copy after login

The first thing to notice is that the code is mostly the same. The biggest differences are that we directly extend the HTMLButtonElement, and then we also declare that we extend the button when we define the custom element.

We also spend a lot less time writing out code for rendering the element. Since we are extending the HTMLButtonElement, the component is just an HTML button with extra power. We will tell an HTML button that it is a "my-button" by using the HTML "is" attribute.

Here is the example live:

Again you'll notice that we are using the "is" attribute to augment the existing HTML button element. You'll also notice that just like with the Autonomous custom elements, we can attach event listeners and work with the button just like we would for any other HTML element, which makes more sense here anyway because it literally is just an extended HTML button.

Wrapping Up

Web components are a vanilla way to solve the problem of creating shareable components that can be reused across different pages and projects. They work more like normal HTML elements, which can cause some confusion, but in the end they can be extremely useful and help solve a lot of the same problems that modern frameworks are targeting.

Here we've taken a very introductory look into web components, the different concepts around them, and some quick examples showcasing their basic function. From here we can start taking deeper dives into how we can make building and using them easier, and look into how we can deal with some of their pain points.

If you're interested, feel free to view the examples in GitHub, or you can play with them in Code Pen.

  • Autonomous Custom Element Example
  • Custom Built-In Element Example
  • Bonus Basic Templates Example!

In the next article, we will take a look at how we can expand on using templates and slots, and how we can make rendering easier. Stay tuned!

The above is the detailed content of Web Components: An Introduction. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

What should I do if I encounter garbled code printing for front-end thermal paper receipts? What should I do if I encounter garbled code printing for front-end thermal paper receipts? Apr 04, 2025 pm 02:42 PM

Frequently Asked Questions and Solutions for Front-end Thermal Paper Ticket Printing In Front-end Development, Ticket Printing is a common requirement. However, many developers are implementing...

Demystifying JavaScript: What It Does and Why It Matters Demystifying JavaScript: What It Does and Why It Matters Apr 09, 2025 am 12:07 AM

JavaScript is the cornerstone of modern web development, and its main functions include event-driven programming, dynamic content generation and asynchronous programming. 1) Event-driven programming allows web pages to change dynamically according to user operations. 2) Dynamic content generation allows page content to be adjusted according to conditions. 3) Asynchronous programming ensures that the user interface is not blocked. JavaScript is widely used in web interaction, single-page application and server-side development, greatly improving the flexibility of user experience and cross-platform development.

Who gets paid more Python or JavaScript? Who gets paid more Python or JavaScript? Apr 04, 2025 am 12:09 AM

There is no absolute salary for Python and JavaScript developers, depending on skills and industry needs. 1. Python may be paid more in data science and machine learning. 2. JavaScript has great demand in front-end and full-stack development, and its salary is also considerable. 3. Influencing factors include experience, geographical location, company size and specific skills.

How to merge array elements with the same ID into one object using JavaScript? How to merge array elements with the same ID into one object using JavaScript? Apr 04, 2025 pm 05:09 PM

How to merge array elements with the same ID into one object in JavaScript? When processing data, we often encounter the need to have the same ID...

Is JavaScript hard to learn? Is JavaScript hard to learn? Apr 03, 2025 am 12:20 AM

Learning JavaScript is not difficult, but it is challenging. 1) Understand basic concepts such as variables, data types, functions, etc. 2) Master asynchronous programming and implement it through event loops. 3) Use DOM operations and Promise to handle asynchronous requests. 4) Avoid common mistakes and use debugging techniques. 5) Optimize performance and follow best practices.

How to achieve parallax scrolling and element animation effects, like Shiseido's official website?
or:
How can we achieve the animation effect accompanied by page scrolling like Shiseido's official website? How to achieve parallax scrolling and element animation effects, like Shiseido's official website? or: How can we achieve the animation effect accompanied by page scrolling like Shiseido's official website? Apr 04, 2025 pm 05:36 PM

Discussion on the realization of parallax scrolling and element animation effects in this article will explore how to achieve similar to Shiseido official website (https://www.shiseido.co.jp/sb/wonderland/)...

The Evolution of JavaScript: Current Trends and Future Prospects The Evolution of JavaScript: Current Trends and Future Prospects Apr 10, 2025 am 09:33 AM

The latest trends in JavaScript include the rise of TypeScript, the popularity of modern frameworks and libraries, and the application of WebAssembly. Future prospects cover more powerful type systems, the development of server-side JavaScript, the expansion of artificial intelligence and machine learning, and the potential of IoT and edge computing.

The difference in console.log output result: Why are the two calls different? The difference in console.log output result: Why are the two calls different? Apr 04, 2025 pm 05:12 PM

In-depth discussion of the root causes of the difference in console.log output. This article will analyze the differences in the output results of console.log function in a piece of code and explain the reasons behind it. �...

See all articles