要約

  • W3C が2012年5月に出した最初の公開草案は DOM の部分木を分ける機能的境界を示した。2014年草案は複数の木の合成を扱い、2018年の Note は関連規則が DOM、HTML、CSS Scoping などへ移ると記した。
  • 現在の DOM では、ページ側の子ノードを shadow tree の slot に割り当てられる。ノードの親子関係はそのままで、表示上の位置が決まる。:host、::slotted、::part は CSS 側で用意された接点だ。

ニュースカードを一つ想像してほしい。部品の作者は、ボタンの形や余白をきちんと決めた。ページの編集者は写真と見出しを入れたい。ところがページ全体の巨大な CSS がボタンを蛍光緑に塗り替えたら、カードの作者は泣く。反対にカードを完全に閉じたら、編集者はニュースを入れられない。必要だったのは頑丈な金庫ではなく、予約できる入口だった。

2012年5月22日の W3C 最初の公開作業草案は、一つの文書にある DOM 部分木の間に機能的な境界を置く構想を示した。部品は内部構造を持ちながらページに参加する。2014年6月17日の作業草案では、複数の木を一つの見える階層へどう合成するかが前面に出る。初期草案の細部を今のブラウザーにそのまま当てはめるより、当時何を解こうとしていたかを読むのが面白い。

その後、規則は一冊の文書から出ていった。2018年3月1日の W3C 作業部会 Noteは、Shadow DOM の内容が DOM、HTML、CSS Scoping、UI Events などへ取り込まれていると説明する。建物の骨組み、内装、来客時の振る舞いが、それぞれの設計図に収まった。独立文書の役割が変わっても、部品の境界という問題はブラウザーの中心に残った。

現在の WHATWG DOM Living Standardに沿ってカードを分解すると、まずページ上の要素が host になる。そこに shadow root が付き、その下に部品内部の木がある。ページが host に渡す普通の子ノードは light tree 側にいる。部品内部の slot は、それらの子ノードを表示上の席へ割り当てる。写真がカードの上段に見えても、DOM の親が shadow root に変わったわけではない。表示の座席表とノードの戸籍は別物だ。

この差はデバッグで効く。画面上では隣り合う写真とボタンでも、前者はページの子、後者は部品内部の子かもしれない。slot が空なら、部品が用意した代替内容を見せられる。見た目だけで木の親子関係を決めつけると、セレクターや操作の結果が不可解になる。先にどちらの木に属するかを確かめれば、謎はかなり減る。

スタイルの側を説明するのが CSSWG の CSS Shadow Module Level 1 編集草案だ。ページの普通のセレクターが shadow tree の内部へ勝手に進み、全てを塗り替える構造にはしない。その一方で、部品は明示的な取っ手を付けられる。:host は部品側から host を扱い、::slotted は割り当てられた内容に限定して働く。::part では内部の一部に名前を付け、外側からスタイルを調整できるようにする。店のショーウィンドーを開けるのであって、倉庫の鍵束を渡すわけではない。

CSS の文書は編集草案であり、ここでは設計を説明する原典として読む。年表は W3C の2012年、2014年、2018年の記録が支える。五つの資料が描くのは、二人の作者による共同制作だ。ページが中身を持ち寄り、部品が置き場所と公開する表面を決め、ブラウザーが一枚のカードとして見せる。