🎄Open UI Advent Calendar: Day 18 / Customizable Select Element Ep.16
Published on
Updated on
Customizable Select Elementの関連仕様: `<selectedcontent>` - Light DOMへのクローン追加実装に関して、CSSWGとの合意形成。UAによるLight DOMへのNodeクローンタイミングに関する懸念を深掘る
Table of Contents
Table of Contents
はじめに
Ep.15では、<selectedoption>を用いて、宣言的に選択された<option>の中身を Light DOM にクローンする提案が、合意を得た詳細についてお話ししました。
「Light DOM は Author の領域であり、UA によって変更されるべきではない」という制約に対して、今回その境界を越える提案が可決されたことによって、HTML 史上初となる、UA から Light DOM への変更を加える実装がなされていきます。
その初の試みとなる<selectedoption>は、もちろん実装上の課題も多く、その解決策を模索する議論が続いています。
今回からは、その関連 Issue を中心に、<selectedoption>の実装に関する議論の現状を追っていきます。
※ <selectedoption>は、2024/12 現在、<selectedcontent>にリネームされています。
混乱を避けるため、本エントリからは最新版の<selectedcontent>と表記します。
RESOLVED: rename the selectedoption element to selectedcontent
https://github.com/openui/open-ui/issues/1112#issuecomment-2450527487
- select: Naming of
<selectedoption>· Issue #1112 · openui/open-ui - [Customizable select] Rename selectedoption to selectedcontent by brechtDR · Pull Request #1124 · openui/open-ui
- Rename
<selectedoption>to<selectedcontent>by chromium-wpt-export-bot · Pull Request #49046 · web-platform-tests/wpt

2024/12/9時点でのselectの各パーツの定義
<selectedcontent>の実装に関するIssueまとめ
2024/12 現在、<selectedcontent>の実装に関する Issue は次の通りです。そのうちのいくつかは、現在進行形で議論が続いています。
(※ 時系列で列挙)
- How to implement and shape API for
<selectedoption>element for<select>· Issue #10242 · w3c/csswg-drafts - Timing of cloning for the
<selectedoption>element · Issue #10520 · whatwg/html - select: Should
<selectedoption>respond to mutations in the selected<option>· Issue #825 · openui/open-ui - selectlist: Animating changes in the selected value · Issue #824 · openui/open-ui
- select: clarifying what should be used as the chosen value · Issue #1117 · openui/open-ui
- select: Should
<selectedoption>update when selecting the already-selected option · Issue #1119 · openui/open-ui
これらの中でも、筆者が特に注目している、「クローンタイミング」に関する 1~4 の Issue に焦点を当てて、その内容について深掘っていきます。
How to implement and shape API for <selectedoption> element for <select>
本格的な実装に移る前に、実装の方針をより具体的に固めるための Issue が CSSWG に出されました。
Open UI での議論は、WHATWG の見解をもとに Light DOM 実装でいくという議論結果となりました。しかし、Light DOM で実装するか、Shadow DOM で実装するかで、CSS の受ける影響が大きいため、CSSWG からの意見を募る Issue が持ちかけられたということです。
上記の仕様を実現するために、次のようなマークアップになることが固まっています。
<select>
<button type="popover">
<selectedoption></selectedoption>
</button>
<datalist>
<option>
<img src="country1.jpg" />
<span>Country 1</span>
</option>
<option>
<img src="country2.jpg" />
<span>Country 2</span>
</option>
</datalist>
</select>
未確定なのが、「クローンされた DOM を<selectedcontent>内に追加する実装」の部分です。これには 2 通りの実装方法が考えられます。
<selectedcontent>をLight DOMで実装した場合
WHATWG の見解に従い、<selectedcontent>を Light DOM とし、その子 Node をcloneNode()の結果で置換する方法です。
この方法であれば、Author はselectedcontentセレクタを直接利用できるため、<option>と<selectedcontent>を別々にスタイルできます。
全てが Light DOM の管理下のため、UA での CSS 追加実装は不要です。
selectedcontent > span {
display: none;
}
<selectedcontent>をShadow DOMで実装した場合
Shadow DOM で実装する場合、<selectedcontent>を UA Shadow Root とし、その子 Node をcloneNode()の結果で置換する方法です。
UA Shadow Root の中は、(<input>の内部<div>はスタイルできない、など)Author スタイルシートからアクセスできないため、新しい擬似要素を定義して Author にスタイリングする術を提供する必要があります。そのため、CSS に新しいシンタックスを追加する必要が出てきます。
selectedcontent::selectedcontent-content > span {
display: none;
}
それだけでなく、Light DOM を動的に UA の Shadow Root に挿入するとなると、一度廃止された過去のあるSanitizer APIの再実装が完了することも条件となります。
これに関して、Open UI と CSSWG の Joint Session で懸念点の洗い出しが行われました。
まず、Shadow DOM での実装については、Sanitizer API の実装と CSS の新しいシンタックスが必要になるため、Light DOM での実装が優先して議論されます。
Light DOM で実装する場合に、主に「クローンのタイミング」に関する懸念点が挙げられました。
初期の案では、クローンする子 Node が動的に変更された場合は、最初は MutationObserver で実装されることになっていました。
MutationObserver APIは、マイクロタスクで変更を検知する API です。そして、マイクロタスクは、タスクが空になるまで、非同期的に実行される仕様になっています。