attachShadowとShadow Root
ホスト要素にカプセル化されたシャドーツリーを作成します
「attachShadowとShadow Root」はCoddyKit上の無料HTML Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはHTML Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 HTML Academyコースには全4レッスンが含まれています。
Shadow DOM とは
Shadow DOM を使うと、要素に独自の隔離された DOM ツリー(「shadow tree」)を持たせることができます。このツリーはページのメイン DOM には現れません。外側の CSS は内側に漏れず、内側の CSS も外側に漏れないため、コンポーネントの完全なカプセル化に適しています。
Shadow Root のアタッチ
カスタム要素の constructor または connectedCallback から this.attachShadow({ mode: "open" }) を呼び出します。このメソッドは ShadowRoot を返し、innerHTML、appendChild などを使って通常の DOM ツリーと同じように内容を追加できます。
class MyCard extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: "open" });
shadow.innerHTML = "<style>p{color:red}</style><p>Hello</p>";
}
}open モードと closed モード
mode: "open" は、shadow tree を element.shadowRoot として公開します。mode: "closed" はこれを隠すため、element.shadowRoot は null を返し、外部のスクリプトはツリーに入れません。実際には、要素を定義したコードが自身の参照を保持できるため、closed はほとんど役に立ちません。
スタイルのカプセル化
shadow tree 内で定義したスタイル(<style> または adopted stylesheets 経由)は、その shadow tree の内部にだけ適用されます。メインドキュメントの CSS セレクターが shadow の子孫要素に一致することはなく、shadow のスタイルがドキュメント側に漏れ出すこともありません。
:host セレクター
shadow tree の内部からホスト要素(カスタム要素自体)を選択するには、特殊な :host 擬似クラスを使います。:host(.large) はホストが .large クラスを持つ場合に一致し、:host([disabled]) はホストが disabled 属性を持つ場合に一致します。
:host {
display: block;
padding: 16px;
border: 1px solid #ccc;
}
:host([disabled]) {
opacity: 0.5;
pointer-events: none;
}カスタム要素で display: block を使う
カスタム要素のデフォルトは display: inline です。shadow root 内で :host { display: block } を適用すると、要素がブロックレベルのコンポーネントとして動作します。これを忘れると、「width: 100% が無視される」というバグのよくある原因になります。
イベントのコンポジション
shadow tree の外側へバブルするイベントは、ホストを起点としてリターゲティングされます。内部のボタンをクリックすると、外側のリスナーには event.target === host として届きます。実際の内部ターゲットを確認する必要がある場合は、event.composedPath() を使ってください。
カスタムイベントで composed: true を使用する
シャドウルート内でディスパッチされたカスタムイベントは、bubbles: true と composed: true の両方を指定して作成しない限り、境界を越えません。composed を指定しない場合、ホストの外側にあるリスナーからイベントを確認することはできません。
スクリプトから内部にアクセスできない
外部のスクリプトからホスト要素を検索することはできますが、そのシャドウ内の子孫要素を検索することはできません。シャドウツリー内に <span> がある場合、document.querySelector("my-card span") は何も返しません。カプセル化により、内部実装が意図せず結合されることを防げます。
宣言的な Shadow DOM
要素の HTML 内に <template shadowrootmode="open"> を記述すると、JavaScript を使わずに、ブラウザーが解析時にシャドウツリーを構築します。これにより、サーバーでレンダリングされたコンポーネントはハイドレーションに適したものになります。JavaScript が実行される前にシャドウツリーが存在するためです。
パフォーマンスに関する考慮事項
シャドウルートごとに、追加のスタイルスコープや追加の描画レイヤーなどのオーバーヘッドが発生します。数百個のシャドウルートであれば問題ありませんが、数万個になると影響が出る可能性があります。非常に高密度な UI(大規模なテーブルや仮想化リスト)では、プロファイリングを行い、Shadow DOM のコストが許容範囲内であることを確認してください。
理解度チェック
open モードでできて、closed モードではできないことは何ですか。
まとめ
attachShadow({ mode: "open" }) は、CSS と ID がどちらの方向にも漏れ出さない、分離された DOM サブツリーを作成します。:host でホスト要素をスタイルし、display: block を忘れずに指定してください。また、外部へ伝播させる必要があるイベントには composed: true を使用します。それ以外では、シャドウツリーは通常の DOM と同じように動作し、内部で innerHTML、appendChild、querySelector を通常どおり使用できます。
よくある質問
「attachShadowとShadow Root」レッスンは無料ですか?
はい。「attachShadowとShadow Root」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、HTML Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 HTML Academyコースには全4レッスンが含まれています。
「attachShadowとShadow Root」で何を学びますか?
ホスト要素にカプセル化されたシャドーツリーを作成します ブラウザで直接実行するハンズオンコードでHTML Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
HTML Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのHTML Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「attachShadowとShadow Root」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このHTML Academyレッスンでコードを書いて実行できますか?
はい。すべてのHTML Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- attachShadowとShadow Root
- コンテンツ配分のためのSlot要素
- Shadow DOM内のスコープ付きスタイル
- 外部スタイル設定のためのpartとexportparts