Skip to main content

🧩 Web Components

Reusable custom HTML elements

The LEGO Brick Analogy

LEGO bricks:

  • Standard shapes: Snap together easily
  • Reusable: Use same brick many times
  • Self-contained: Complete on their own
  • Combinable: Build complex things from simple pieces

Web Components are LEGO bricks for the web. Create custom HTML elements that are reusable and encapsulated.


What Are Web Components?

Web Components = Native browser feature for custom elements

Create your own HTML tags:
  <user-card name="Alice" avatar="alice.jpg"></user-card>
  <star-rating value="4"></star-rating>
  <date-picker></date-picker>

Works like built-in elements (<video>, <select>).
No framework required.

The Three Technologies

1. Custom Elements

Define new HTML elements.
Lifecycle hooks for creation, connection, etc.

customElements.define('user-card', UserCard);

Now <user-card> works in HTML.

2. Shadow DOM

Encapsulated DOM tree.
Styles don't leak in or out.

Component:
  #shadow-root
    <style> p { color: red; } </style>
    <p>Only I am red</p>

Page's <p> elements are not affected.

3. HTML Templates

Reusable markup templates.
Not rendered until used.

<template id="card-template">
  <div class="card">
    <slot name="title"></slot>
    <slot name="content"></slot>
  </div>
</template>

Clone and use as needed.

How They Work Together

1. Define template (HTML structure)
2. Create custom element class
3. Attach shadow DOM for encapsulation
4. Clone template into shadow DOM
5. Register with customElements.define()
6. Use in HTML like any element

Custom Elements Lifecycle

connectedCallback()
  Element added to DOM.
  Set up, fetch data.

disconnectedCallback()
  Element removed from DOM.
  Clean up, remove listeners.

attributeChangedCallback()
  Observed attribute changed.
  React to changes.

adoptedCallback()
  Element moved to new document.
  (Rare)

Shadow DOM Explained

Encapsulation

Styles inside shadow DOM:
  Don't affect outside.
  Not affected by outside.

No more:
  "Why is my component styled wrong?"
  "Why did my component break the page?"

Light DOM vs Shadow DOM

Light DOM:
  Regular children in HTML.
  Visible in page source.

Shadow DOM:
  Hidden internal structure.
  Encapsulated from outside.

<my-element>           ← Light DOM (user provides)
  #shadow-root         ← Shadow DOM (component owns)
    <style>...</style>
    <div>
      <slot></slot>    ← Light DOM rendered here
    </div>
</my-element>

Slots

Placeholders for content.
User provides, component places.

Component:
  <div class="card">
    <slot name="title"></slot>
    <slot name="content"></slot>
  </div>

Usage:
  <my-card>
    <h2 slot="title">Hello</h2>
    <p slot="content">World</p>
  </my-card>

Flexible composition.

Benefits

1. Framework Agnostic

Works everywhere:
  React, Vue, Angular, vanilla JS

Build once, use anywhere.
No lock-in.

2. Encapsulation

Styles scoped automatically.
No CSS conflicts.
Less likely to cause CSS conflicts across pages.

3. Reusability

Package as npm module.
Share across projects.
True component portability.

4. Native Browser Support

No framework needed.
Works in all modern browsers.
Progressively enhanced.

Challenges

1. Learning Curve

Different from React/Vue patterns.
Lifecycle methods.
Shadow DOM quirks.

2. SSR Complexity

Server doesn't know custom elements.
Declarative Shadow DOM helps (newer).

3. Form Compatibility

Custom elements and forms can be tricky.
ElementInternals API helps.

When to Use

Good Fit

✓ Design system components
✓ Shareable across frameworks
✓ Third-party embeddable widgets
✓ Long-lived reusable components
✓ Company-wide component libraries

Maybe Not

✗ App-specific components (use framework)
✗ Quick prototypes
✗ Teams invested in one framework

Tools and Libraries

Lit:
  Google's library for Web Components.
  Simplified syntax.

Stencil:
  Compiler for Web Components.
  TypeScript, JSX.

Shoelace:
  Ready-made component library.
  Built on Web Components.

Browser Support

Modern browsers: Full support!
  Chrome, Firefox, Safari, Edge

Legacy (IE11):
  Polyfills available.

Common Mistakes

1. Forgetting Shadow DOM Mode

attachShadow({ mode: 'open' })

'open': JavaScript can access shadow root.
'closed': Can't access from outside.

Usually use 'open'.

2. Not Observing Attributes

static get observedAttributes() {
  return ['name', 'value'];
}

Without this, attributeChangedCallback won't fire.

3. Heavy Shadow DOMs

Creating shadow DOM for every tiny thing.
Overhead adds up.
Use when encapsulation needed.

FAQ

Q: Web Components vs React?

Web Components: Native, encapsulated, framework-agnostic React: Full framework, virtual DOM, ecosystem

Use both! React can render Web Components.

Q: Can I style from outside?

Use CSS custom properties (variables). Or ::part() selector.

Q: Are they production-ready?

Yes! Used by Google, Salesforce, many others.

Q: Should I build everything as Web Components?

No. Use for reusable, shared components. App-specific components can use frameworks.


Summary

Web Components let you create custom, reusable, encapsulated HTML elements using native browser features.

Key Takeaways:

  • Custom Elements: Define new HTML tags
  • Shadow DOM: Encapsulated styles and markup
  • HTML Templates: Reusable structures
  • Framework agnostic: Works everywhere
  • Great for design systems
  • Lit and Stencil simplify development

Web Components: The native way to build reusable UI!

Leave a Comment

Comments (0)

Be the first to comment on this concept.

Comments are approved automatically.