Web Componentsの基本
Web Componentsは、独自のHTMLタグ(カスタム要素)を定義して再利用できるブラウザ標準の仕組みです。customElements.define で要素名とクラスを結びつけ、Shadow DOMでスタイルとマークアップをカプセル化します。
カスタム要素名には必ずハイフンを含める必要があります(例: my-card)。ハイフンのない名前は標準要素と区別できず、登録できません。これだけで描画されないことがあります。
Shadow DOMは要素の内部構造を外部から隔離する仕組みで、外のCSSが中に入らず、中のスタイルも外に漏れません。この分離が、スタイルが当たらない原因にもなります。
描画されない典型パターン
最も多いのは、customElements.define を呼ぶスクリプトの読み込みより前にカスタム要素がHTMLに書かれていて、登録される前にブラウザが解釈してしまうケースです。登録後にアップグレードされる仕組みはありますが、スクリプトエラーで define 自体が実行されないと永遠に空のままです。
スクリプトの読み込み失敗やJS内のエラーで define に到達していないことも多く、コンソールにエラーが出ていないか確認するのが基本です。同じ名前で二重に define しようとするとエラーになる点にも注意します。
Shadow DOMを使っている場合、外部のCSSは中の要素に届かないため「スタイルが当たらない」と見えることがあります。これは不具合ではなく仕様による分離です。
症状別チェック表
Web Components(カスタム要素)が描画されないときの原因と対処は、症状を分けずに直そうとすると原因探しが長引きます。まず「自分だけで起きるのか」「全員で起きるのか」「特定ブラウザだけか」「差し替え後だけか」を切り分けます。
確認順序を固定すると、相対パス、ファイル名、キャッシュ、認証、外部読み込みのどこで止まっているかが見えます。修正後はローカル確認だけで終わらせず、実際の共有URLで再表示して、相手と同じ条件で直ったことを確認します。
- 自分だけ表示されない: キャッシュ、ログイン状態、ブラウザ拡張、端末幅を確認する
- 全員で表示されない: ファイル構成、相対パス、大文字小文字、アップロード漏れを見る
- 一部だけ崩れる: CSS/画像/JSごとに読み込みエラーを分ける
- 差し替え後だけ古い: URL、キャッシュ、更新対象ファイルの取り違えを確認する
原因を切り分ける手順
登録の問題かスタイルの問題かを分けて確認すると、対処の方向がはっきりします。
- 開発者ツールのConsoleでJSエラーが出ていないか確認する
- カスタム要素名にハイフンが含まれているか確認する
- define を呼ぶスクリプトが実際に読み込まれ、実行されているか確認する
- ElementsタブでShadow DOM(#shadow-root)の中に要素が生成されているか確認する
- スタイルが当たらない場合、Shadow DOM内にstyleを置くか CSS custom properties で外から渡す
- 同名要素を二重定義していないかを確認する
Shadow DOMとスタイル分離の扱い
Shadow DOMの分離は意図的な設計で、コンポーネントが外部のCSSに影響されない利点があります。逆に、外からまとめてスタイルを当てたい場合は、CSS変数(custom properties)や ::part を使って意図的に通り道を作る必要があります。
「グローバルCSSで色を変えたのに反映されない」と感じたら、対象がShadow DOMの中にいないか確認します。中にいるなら、外から直接セレクタで指定する方法は基本的に効きません。
Shadow DOMを使わない(Light DOM)構成にすれば外部CSSは届きますが、その分カプセル化の利点は失われます。要件に応じて選びます。
確認共有の場面での点検
カスタム要素を含むHTMLをレビューに出すとき、相手の環境で描画されないと不具合に見えますが、実際はスクリプトの読み込み順やJSエラーが原因のことが多いです。共有前に開発者ツールでコンソールとShadow DOMの中身を確認しておくと、報告の切り分けが速くなります。
ギガサイト便はCSS/JS/画像を含むZIPをドロップして共有でき、同じURLのまま差し替えられます。コンポーネントの登録順やスタイルを直した版をすぐ反映して再確認してもらえるので、Web Componentsの挙動確認と相性が良い使い方です。
よくある質問
カスタム要素が空のまま描画されないのはなぜですか
customElements.defineが実行されていないことが多いです。スクリプトの読み込み失敗やJSエラーでdefineに到達していないか、要素名にハイフンがないなどの登録条件の不備を確認してください。
外部CSSがカスタム要素に効きません
Shadow DOMを使っていると、外部CSSは内部の要素に届きません。これは仕様による分離です。CSS変数や::partで意図的に通り道を作るか、Light DOM構成にする必要があります。
登録順はどう確認すればよいですか
defineを呼ぶスクリプトが読み込まれ、コンソールにエラーが出ていなければ、要素はあとからアップグレードされます。Elementsタブで#shadow-rootの中身が生成されているかを見ると、登録の成否が分かります。
同じ要素名で二重に定義するとどうなりますか
同名のカスタム要素を二度defineしようとするとエラーになり、以降の処理が止まることがあります。コンソールにエラーが出ていないか確認し、定義が重複していないか点検してください。
原因が分からないときはどこから確認すべきですか?
まず自分だけの問題か全員の問題かを分けます。次にシークレットウィンドウ、別ブラウザ、スマホで確認し、ファイル構成・相対パス・キャッシュ・認証設定を順に見ます。