Web Componentsとは?Custom ElementsとShadow DOMで作る次世代UI

Web Componentsとは、ブラウザがネイティブに提供する仕組みを使って、UIパーツを再利用可能なコンポーネントとして定義・利用できる技術です。ReactやVueのようなフレームワークがなくても、HTML・CSS・JavaScriptだけで独自の要素(カスタム要素)を作成し、DOMに組み込めるのが特徴です。

Web Componentsを構成する3つの要素

Web Componentsは以下の3つの技術で構成されています:

1. Custom Elements(カスタム要素)

自分で新しいHTMLタグを定義できます。例えば、<my-card> のような独自のカード要素を定義して再利用できます。

<my-card title="お知らせ">
  このコンポーネントはカスタム要素で作られています。
</my-card>
my-card{
  display: block;
  width: 50%;
}
my-card .card-title{
  color: red;
}
class MyCard extends HTMLElement {
  connectedCallback() {
    const title = this.getAttribute('title') || 'タイトル';
    const content = this.innerHTML;
    this.innerHTML = `
      <style>
        .card {
          border: 1px solid #ccc;
          border-radius: 8px;
          padding: 16px;
          box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.1);
          background: #fff;
        }
        .card-title {
          font-size: 1.25rem;
          margin-bottom: 0.5rem;
        }
        .card-content {
          font-size: 1rem;
          color: #555;
        }
      </style>
      <div class="card">
        <div class="card-title">${title}</div>
        <div class="card-content">
          ${content}
        </div>
      </div>
    `;
  }
}
customElements.define('my-card', MyCard);
実際にデモで確認する

2. Shadow DOM(シャドウDOM)

Shadow DOM(シャドウDOM)は、カスタム要素(Custom Elements)の内部実装を外部から隔離し、スタイルや構造の衝突を防ぐための仕組みです。Custom Elementsが"何をするか"(ロジックやマークアップ)を定義するものだとすれば、Shadow DOMはその"内部をどう守るか"というカプセル化のための技術です。

カスタム要素とシャドウDOMの違い

観点Custom ElementsShadow DOM
目的独自のタグ(要素)を定義する内部構造とスタイルを外部から分離・保護する
主な用途<my-button>のようなタグを作る.cardなどの内部クラスを外部CSSと隔離する
スタイルの範囲外部CSSが影響する完全にカプセル化(影響しない)
使用方法customElements.define()attachShadow({ mode: 'open' })

たとえば、以下のようにShadow DOMを用いて内部の構造とスタイルを閉じ込めることで、他のCSSの影響を一切受けないコンポーネントが作れます。

<my-card title="お知らせ">
  このコンポーネントはシャドウDOMで作られています。
</my-card>
my-card{
  display: block;
  width: 50%;
}
/* シャドウDOMでは以下のスタイルは適応されません。 */
my-card .card-title{
  color: red;
}
class MyCard extends HTMLElement {
  constructor() {
    super();
    const shadow = this.attachShadow({ mode: 'open' });
    shadow.innerHTML = `
      <style>
        .card {
          border: 1px solid #ccc;
          border-radius: 8px;
          padding: 16px;
          box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.1);
          background: #fff;
        }
        .card-title {
          font-size: 1.25rem;
          margin-bottom: 0.5rem;
        }
        .card-content {
          font-size: 1rem;
          color: #555;
        }
      </style>
      <div class="card">
        <div class="card-title">${this.getAttribute('title') || 'タイトル'}</div>
        <div class="card-content">
          <slot></slot>
        </div>
      </div>
    `;
  }
}
customElements.define('my-card', MyCard);

実際にデモで確認する

このように、Shadow DOMを使うことで、再利用可能かつ壊れにくいUIコンポーネントを作ることが可能になります。

slotタグとは?

<slot>タグは、Web Componentsの中に外部から渡された内容(子要素)を挿入するための差し込み口です。これにより、再利用可能なコンポーネントの中に動的なコンテンツを埋め込むことができます。

たとえば以下のように定義された<my-card>コンポーネントに対して

<my-card>
  <p>この文章はslotに挿入されます。</p>
</my-card>

JavaScript側で以下のように定義したとします。

shadow.innerHTML = `
  <div class="card">
    <slot></slot>
  </div>
`;

この場合、<slot></slot>の部分に<p>この文章はslotに挿入されます。</p>が挿入され、結果的に次のような表示になります。

<div class="card">
  <p>この文章はslotに挿入されます。</p>
</div>

また、<slot name="header">のように名前付きスロットを使えば、複数の挿入位置を指定できます。これはデザインの柔軟性を高め、より高度なコンポーネント設計を可能にします。

shadow.innerHTML = `
  <div class="card">
    <div class="card-header">
      <slot name="header"></slot>
    </div>
    <div class="card-content">
      <slot name="content"></slot>
    </div>
  </div>
`;

このような構成に対して、以下のようにHTMLを書けば、名前で紐づいた内容がそれぞれのslotに挿入されます。

<my-card>
  <h2 slot="header">お知らせ</h2>
  <p slot="content">この内容はカードの本文として表示されます。</p>
</my-card>

このように、slotにnameを付けることで、マルチパートなコンポーネント設計が可能になります。

3. HTML Templates(テンプレート)

テンプレートは、再利用可能なHTML構造を非表示の状態で定義しておき、必要なタイミングでJavaScriptから呼び出してDOMに挿入するための仕組みです。主にコンポーネントのインスタンス化を簡略化したいときや、遅延描画したい場合に役立ちます。

<template>要素は、HTMLの中にあってもDOMにレンダリングされず、スクリプトから呼び出して初めて活用されます。

以下の例では、ボタンをクリックするとテンプレートからアラート要素を生成して表示します。

<template id="alert-template">
  <div class="alert">
    ⚠ アラートメッセージが表示されました!
  </div>
</template>
<button id="show-alert">アラートを表示</button>
.alert{
  padding: 1em;
  background: #ffd;
  border: 1px solid #cc0;
  margin: 1em 0;
}
document.getElementById('show-alert').addEventListener('click', () => {
  const tmpl = document.getElementById('alert-template');
  const clone = tmpl.content.cloneNode(true);
  document.body.appendChild(clone);
});

実際にデモで確認する

フレームワークとの違い

ReactやVueとの主な違い

特徴Web ComponentsReact/Vue
フレームワーク依存不要(ネイティブ)必要
カプセル化シャドウDOM仮想DOM内で制御
再利用性高い(ブラウザ間で共通)フレームワークに依存
学習コスト中〜高

Web Componentsは、フレームワークに依存せず、純粋なWeb標準技術として使えるため、将来的なメンテナンス性や移植性に優れています。一方、状態管理やルーティングなどの機能は自前で実装が必要になることが多いです。


利用ケースと実例

  • デザインシステムの構築において、ボタンやカードなどのUIパーツを共通化
  • マイクロフロントエンドの実装で、アプリケーション間でのパーツ共有
  • CMSやWordPressテーマでの高再利用性なUIコンポーネントの導入

実際に大手企業やライブラリでもWeb ComponentsベースのUIが採用されています。例:GoogleのMaterial Web Components

GoogleのMaterial Web Componentsとは?

Material Web Componentsは、Material Designのルールに準拠したUIを、ReactやVueといったフレームワークを使わずに導入できるのが大きな特徴です。Googleの公式サポートのもと開発が進められており、Web標準に則った高品質なコンポーネント群として、今後のWebアプリケーション設計において有力な選択肢の一つになると期待されています。

  • 完全なWeb標準対応:フレームワーク非依存で、どんな環境でも使える
  • カスタム要素として提供<md-button><md-checkbox> などが用意されている
  • シャドウDOMとスタイリング:内部構造がカプセル化されており、外部スタイルの影響を受けにくい
  • アクセシビリティ対応:ARIA属性の適用なども組み込まれている

具体的な使用方法や導入手順については、別の記事で詳しく紹介します。


まとめ:Web Componentsはこれからの標準技術

Web Componentsは、HTML/CSS/JSという既存技術で実現できる、軽量かつ再利用可能なコンポーネント開発手法です。特にライブラリやフレームワークに依存しない設計が求められる環境では大きな利点となります。

さらに、Custom Elementsによる独自要素の定義、シャドウDOMによるスタイルのカプセル化や、slotを使った柔軟なコンテンツ挿入、templateタグによる動的DOMの生成など、Web Componentsは多くの現場で求められる要件をネイティブ技術だけで満たすことができます。

ReactやVueといったフレームワークと比べて、導入のハードルは低くありませんが、その分、フレームワークに縛られない長期的な資産としての価値があります。

「小さく作って、広く使う」——そんなUI設計にぴったりの技術が、Web Componentsです。今後のWeb開発において、より一層注目すべき標準技術と言えるでしょう。

Contact

ウェブサイトの制作や運用に関わる
お悩みやご相談
お気軽にお問い合わせ下さい

ウェブサイトと一口に言っても、企業サイトやECサイト、ブログ、SNSなど、その“カタチ”は目的に応じてさまざまであり、構築方法や使用する技術も大きく異なります。株式会社コナックスでは、お客様のご要望やブランドの個性を丁寧に汲み取り、最適なウェブサイトの“カタチ”をご提案いたします。

デザイン、ユーザビリティ、SEO対策はもちろん、コンテンツ制作やマーケティング戦略に至るまで、あらゆるフェーズでお客様のビジネスに寄り添い、成果につながるウェブサイトづくりをサポートいたします。私たちは、ウェブサイトの公開をゴールではなくスタートと捉え、お客様のビジネスの成功に向けて共に伴走してまいります。