🎄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

2024/12/9時点でのselectの各パーツの定義
2024/12/9時点でのselectの各パーツの定義

<selectedcontent>の実装に関するIssueまとめ

2024/12 現在、<selectedcontent>の実装に関する Issue は次の通りです。そのうちのいくつかは、現在進行形で議論が続いています。
(※ 時系列で列挙)

  1. How to implement and shape API for <selectedoption> element for <select> · Issue #10242 · w3c/csswg-drafts
  2. Timing of cloning for the <selectedoption> element · Issue #10520 · whatwg/html
  3. select: Should <selectedoption> respond to mutations in the selected <option> · Issue #825 · openui/open-ui
  4. selectlist: Animating changes in the selected value · Issue #824 · openui/open-ui
  5. select: clarifying what should be used as the chosen value · Issue #1117 · openui/open-ui
  6. 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 で懸念点の洗い出しが行われました。

[CSSWG] OpenUI-WHATWG/HTML-CSSWG Meeting 2024-07-25 from Dael Jackson on 2024-07-26 (www-style@w3.org from July 2024)
[CSSWG] OpenUI-WHATWG/HTML-CSSWG Meeting 2024-07-25 from Dael Jackson on 2024-07-26 (www-style@w3.org from July 2024) favicon lists.w3.org

まず、Shadow DOM での実装については、Sanitizer API の実装と CSS の新しいシンタックスが必要になるため、Light DOM での実装が優先して議論されます。

Light DOM で実装する場合に、主に「クローンのタイミング」に関する懸念点が挙げられました。

初期の案では、クローンする子 Node が動的に変更された場合は、最初は MutationObserver で実装されることになっていました。

MutationObserver APIは、マイクロタスクで変更を検知する API です。そして、マイクロタスクは、タスクが空になるまで、非同期的に実行される仕様になっています。