静的サイトにLight DOM Web Componentsという選択肢 (HonoXでの利用例もあるよ)
はじめに
AstroやHono (JSX/HonoX) などの静的サイトジェネレーターでサイトを構築する際、タブやダイアログといったインタラクティブなUIコンポーネントをどう実装するかは悩ましい問題です。アイランドアーキテクチャでReactを使う、Alpine.jsを使う、Vanilla JSで頑張る…など、選択肢はいくつかありますが、どれも一長一短。静的サイトの良さを活かしつつ、動的な要素も手軽に追加したい、そんな要望に応えるのが難しいと感じることもあります。
そこで、この記事では、Light DOM Web Components という選択肢を提案します。静的サイトのメリットを損なわず、それでいてリッチなUIを簡単に実現できる可能性を秘めたWeb Componentsのアイデアを解説します。
Light DOM Web Componentsとは?
Web Components は、再利用可能なカスタム要素を作成するための標準技術です。大きく分けて、以下の3つの技術から構成されています。
- Custom Elements: 独自のHTMLタグを定義し、その振る舞いをJavaScriptで記述できます。
- Shadow DOM: 要素の内部構造(DOMツリー)とスタイルをカプセル化し、外部からの影響を受けにくくします。
-
HTML Templates:
<template>
と<slot>
要素を使って、再利用可能なHTMLの断片を定義できます。
ここでポイントとなるのが Shadow DOM です。通常、Web Components は Shadow DOM を利用してカプセル化を行います。しかし、Shadow DOM は外部からのスタイル適用が難しく、静的サイトとの相性があまり良くない場合があります。
そこで注目したいのが Light DOM です。Light DOM は Shadow DOM を使わず、通常のDOMツリー上にカスタム要素を展開します。これにより、外部からのスタイル適用が容易になり、静的サイトとの親和性が高まる、というわけです。
Shadow DOMの中は外部のstyleの影響を受けないサンプル
なぜLight DOM Web Componentsを使うのか?
Light DOM Web Components を静的サイトに採用するメリットは数多くあります。
- 宣言的なUI: HTML タグを書くだけで、複雑なUIコンポーネントを簡単に利用できます。
- 再利用性: 一度作成したコンポーネントは、JSさえ読み込めばサイト内のどこでも再利用できます。
- 軽量: 実装にはある程度のJSが必要ですが、機能だけ提供するWeb Componentsにすることで使い回しが手軽にできるため結果として軽量です。
- 保守性: ページごと、作業者ごとに実装を行う必要がないため保守性が高まります。
- フレームワーク非依存: 特定のJavaScriptフレームワーク(React, Vue, Angularなど)に依存しないため、どのような環境でも利用可能です。PHPでもCMSでも利用可能です。
- SEOフレンドリー: Light DOMは通常のDOMとしてレンダリングされるため、検索エンジンクローラーがコンテンツを問題なく認識できます。
- アクセシビリティの向上: カスタム要素に適切なARIA属性を付与することで、アクセシビリティを担保したコンポーネントを構築できます。(Web Componentsに限った内容ではないですが、再利用可能な要素なのできちんと作り込みやすい)
Light DOM Web Componentsのサンプル
ウェブでよく使うアコーディオン、タブ、ダイアログを作ってみました。
- Web Componentsで作る、Radix UIライクなAccordionコンポーネント
- Web Componentsで作る、Radix UIライクなDialogコンポーネント
- Web Componentsで作る、Radix UIライクなTabsコンポーネント
HTMLサンプル
<ui-tabs value="tab1">
<ui-tabs-list>
<ui-tabs-trigger value="tab1"><button>Tab1</button></ui-tabs-trigger>
<ui-tabs-trigger value="tab2"><button>Tab2</button></ui-tabs-trigger>
</ui-tabs-list>
<ui-tabs-panel value="tab1">
Tab1 content
</ui-tabs-panel>
<ui-tabs-panel value="tab2">
Tab2 content
</ui-tabs-panel>
</ui-tabs>
CODEPEN
どうやって使うの?
コーポレートサイトの様なFTPでデータをアップロードする様なサイトでは作成したWeb Componentsを事前にビルドして利用したいサイトで読み込みます。
astroやHonoXのような静的サイトジェネレータであれば読み込んだJSをサイト書き出し時にビルドする仕組みがあるので、そのまま利用できます。
例えばHonoX
サンプルとしてHonoXでWeb Componentsを利用したサイトを用意しました。
設定を変更できる部分はClient Componentsでhono/jsxを利用していますが
タブ、ダイアログ、アコーディオンの各コンポーネントはWeb Componentsを利用しています。
個人的におすすめしたい利用場面
Webサイト制作
コーポレートサイトやLPサイト制作などのWebサイト制作の場面では特にLight DOM Web Componentsはおすすめです。
Light DOM Web Componentsを利用することで、以下のようなメリットが得られます。
柔軟なUI
コーポレートサイトやLPサイトはページごとに異なるUIを提供することもあります。Shadow DOMでは難しいページごとに異なるスタイルもLight DOM Web Componentsなら柔軟なスタイリングが可能です。
開発効率の向上
繰り返し使うUI部品をコンポーネント化することで、開発時間を短縮できます。
多様なスキルセットに対応
HTMLの知識があれば、JavaScriptが得意でないデザイナーやマークアップエンジニアも、ある程度動的なコンテンツを作成できます。
CMS、ヘッドレスCMS
CMSとLight DOM Web Componentsの組み合わせも非常に強力です。
動的コンテンツの容易な組み込み
例えばヘッドレスCMSのコンテンツデータをSPAサイトに読み込む様な場合は基本的にJSを利用したコンテンツは読み込めません。(読み込んだ後に実行させる様な仕組みが必要になる)Web Componentsであればページに配置されたタイミングでJSが実行されるためどの様なタイミングで読み込まれたコンテンツでもインタラクティブな要素が利用可能です。
例えば、お知らせ記事中にアコーディオンでFAQや、ダイアログで画像を表示することも可能です。
JS不要のコンテンツ編集
CMSの編集者は、JavaScriptのコードを一切書くことなく、リッチなコンテンツを作成できます。
エディタの拡張
CMSのエディタ内でカスタム要素を利用することで、タブ、アコーディオンなどのUIを簡単に挿入できるようになります。
おわりに
静的サイト開発で便利に使えそうなLight DOM Web Componentsのアイデアを紹介しました。
どうでしょうか。便利に使える気がしませんか。
ただあまり利用されている場面を見たことがないのが少し気になるところです。なにか大きなデメリットがあったりするんですかね?
Discussion