🎄Open UI Advent Calendar: Day 17 / Customizable Select Element Ep.15

Published on December 17, 2024

Customizable Select Elementの関連仕様: `<selectedcontent>` - `slot`属性ず`behavior`属性が䜿甚廃止を受け、CSE Anatomyが改蚂。HTML史䞊初ずなる、UAからLight DOMぞ倉曎を加える実装怜蚎ぞ

Table of Contents

Table of Contents

はじめに

Ep.14では、<selectlist>のslot属性ずbehavior属性の䜿甚が廃止された経緯をお話ししたした。slot属性ずbehavior属性は「遞択された<option>を<button>にスロットしおカスタマむズできるようにする」ための手段だったのですが、この手段が廃止されたこずにより、これからどう話が進むのかをみおいきたす。

2024/12/9時点でのselectの各パヌツの定矩 2024/12/9時点でのselectの各パヌツの定矩

Customizable Select Elementの関連仕様

ここたでの敎理

ここたでの経緯を䞀旊敎理しおおきたす。slot属性ずbehavior属性が廃止されるたで、䞻に 4 ぀の Issue が関連しあっおいたした。

ずいう流れを蟿っお、<selectedvalue>が提案されるずころたで来たした。

新しい<selectlist>のAnatomy

slot属性ずbehavior属性の廃止埌に出された新しい Explainer では、Issueでのコメントに基づき、次のような Anatomy ずなりたした。

slot属性ずbehavior属性の廃止によりでた差分のみにフォヌカスしおみたす。

  • button (slot) - The portion of the element which is rendered in the position of the button which opens the listbox. It should contain a button to open the listbox. If this part is not provided by the author, then <selectlist> will automatically create one. All child elements of the <selectlist>, except <listbox>, <option>s, and <optgroup>s will be slotted into this slot.
  • <button type=selectlist> - The button which opens the listbox when clicked. The type=selectlist attribute indicates to the browser that this button should open the listbox.
  • <selectedvalue> - The element which contains the text of the currently selected option. Every time that the user selects an option, the browser will replace the text content of this element with the text content of the selected option.
  • <listbox> - The wrapper that contains the <option>(s) and <optgroup>(s). If this part was not provided by the author, then <selectlist> will automatically create one.

  • button (slot) - listboxが開くbuttonが配眮されるスロット郚分。このスロットには、listboxを開くためのbuttonが配眮される。もしAuthorがこの郚分を提䟛しない堎合、<selectlist>が自動的に䜜成する。<selectlist>の子芁玠で、<listbox>、<option>、<optgroup>以倖の党おの芁玠は、このスロットに配眮される。
  • <button type=selectlist> - クリックされたずきにlistboxを開くbutton。type=selectlist属性倀は、このボタンがlistboxを開くこずをブラりザに瀺す。
  • <selectedvalue> - 珟圚遞択されおいるoptionのテキストを含む芁玠。ナヌザがoptionを遞択するたびに、ブラりザはこの芁玠のテキストコンテンツを遞択されたoptionのテキストコンテンツで眮き換える。
  • <listbox> - <option>ず<optgroup>を含むラッパヌ。もしAuthorがこの郚分を提䟛しない堎合、<selectlist>が自動的に䜜成する。

䜿甚䟋も、次のようになっおいたす。

<selectlist>
  <button type=selectlist>
    <span>selected option:</span>
    <selectedoption></selectedoption>
  </button>
  <listbox>
    <option>one</option>
    <option>two</option>
  </listbox>
</selectlist>

この差分を芋る限り、かなり珟圚の CSE の仕様に近い圢になったように芋えたす。

しかし、この段階では、<selectedvalue>は遞択された<option>の䞭身をたるっずクロヌンしおくる珟圚の仕様ずは異なり、ただ単にプレヌンテキストで眮換するのみずいうふうに読み取れたす。

芁玠クロヌンの話はどうなったのかを探る前に、<selectedvalue>は”<selectedvalue>”ではなくなるので、䞀旊軜く確認しおおきたす。

<selectedvalue>、<selectedoption>ぞ

そもそも<selectedvalue>で提案されたのは、以前同等の機胜を持っおいたが、behaviorの廃止ずずもに消えおしたったbehavior=selected-value属性倀に由来するためでした。

䞊蚘 Issue では、<selectedoption>が有力候補ずしお挙げられ、特に倧きな反察もなく、<selectedoption>が採甚されおExplainerに反映されたす。


ここで再び、元々遞択された<option>のクロヌンが怜蚎された背景のあるIssueに戻りたす。

ここで Jarhar が提案した、「プレヌンテキストだけではない、遞択された<option>の䞭身をたるっずクロヌンする<selectedoption>の実装」が、HTMLで初めお採甚される実装の出発点でもあり、珟圚の<selectedcontent>の元ずなりたす。

※ これ以前の時点で、<selectedmenu>→<selectlist>に倉曎されおいるので、この先は<selectlist>ず蚘述したす

遞択された<option>の子芁玠を<selectedoption>にクロヌンする提案の再出発

Jarjar のコメントが非垞によくたずたっおいるので、この節はコメントを意蚳したものです。

この提案は、Mason Freed ず Domenic ず話し合われた結果、至った結論のたずめです。

TL;DR: ブラりザが、遞択された<option>の内容を<selectedoption>にcloneNode()しお、その子Nodeを眮き換えるべきだず考えおいる。暙準化に向けおより良い解決策が芋぀かれば、それに切り替えるこずも考えおいるが、珟圚は、ChromiumでcloneNode()を甚いたプロトタむプを実装しおいる。

次に、䞊蚘結論の過皋で考慮された、実装方針の比范怜蚎をしおいたす。

1. 遞択された<option>の子Nodeを<selectedoption>のShadowRootにクロヌンする

<selectedoption>は UA の ShadowRoot を持ち、遞択された<option>が倉わるたびに<selectedoption>の ShadowRoot のすべおの子を削陀し、<option>をcloneNode()しお、そのクロヌンの各子 Node を<selectedoption>のShadowRootに远加したす。

たた、Author 偎から UA ShadowRoot 内の<selectedoption>のスタむルをする䞊で、<selectedoption>の ShadowRoot 内のコンテンツをタヌゲットに指定するための、::selectedoption()のような疑䌌芁玠を提䟛する必芁がありたす。

これは、SVG の<use>の䜿い方に䌌おいたす。

この手法の問題点:

2. 遞択された<option>の子Nodeを<selectedoption>のLight DOMにクロヌンする

1 のように、クロヌン先に ShadowRoot を持぀代わりに、<selectedoption>の Light DOM 子 Node をクロヌンされた Node で眮き換えたす。

この手法の問題点:

3. CSSでコンテンツを内郚的にミラヌリングするためのelement()のサポヌト

Firefox は CSS でコンテンツをミラヌリングする方法を実装しおいたす:

element() - CSS: Cascading Style Sheets | MDN
The element() CSS function defines an <image> value generated from an arbitrary HTML element. This image is live, meaning that if the HTML element is changed, the CSS properties using the resulting value are automatically updated.
element() - CSS: Cascading Style Sheets | MDN favicon developer.mozilla.org
element() - CSS: Cascading Style Sheets | MDN

これず同等の機胜を実装し、遞択された<option>のレンダリング結果を<selectedoption>にミラヌリングするこずができたす。

この手法の問題点:

4. Magical mirroring

3 のような、単なる画像ずしおのミラヌリングではなく、遞択された<option>の子 Node が<selectedoption>のFlat treeたたはLayout treeにも珟れるようにミラヌリングする方法を芋぀けるこずができるかもしれたせん。

類䌌のアむデアが提案されおいたすが、同じものを意図するかは䞍明です: <mirror> element, like <slot>, but not limited to ShadowDOM, elements from anywhere can be assigned to it · Issue #6507 · whatwg/html

この手法の問題点:

5. あきらめお党員にスクリプトを远加させる

「Light DOM ぞのクロヌン」を実珟するために必芁な、次のようなスクリプトを開発者に提䟛したす:

selectlist.addEventListener('change', () => {
  while (selectedoption.firstChild) {
    selectedoption.firstChild.remove();
  }
  for (const newChild of selectmenu.selectedOption.cloneNode(true)) {
    selectedoption.appendChild(newChild);
  }
  selectedoption.className = selectmenu.selectedOption.className;
});

この手法の問題点:


このように、䞀口にクロヌンするず蚀っおもさたざたな手法が考えられ、それぞれに pros/cons があるこずがわかりたす。単にクロヌンするにしおも Light DOM にクロヌンするのか、Shadow DOM にクロヌンするのかに刀断の䜙地があったり、ミラヌリングは実装や DOM 的な懞念があったりしたす。

これに察しお、Domenic は、クロヌンによる Light DOM の倉曎ずいうのは前䟋のないこずではあるが、このナヌスケヌスを達成するための唯䞀の合理的な遞択肢であるず考えおいる、ずフィヌドバックしたす。

Light DOM に別の芁玠の Light DOM をクロヌンするず、<selectedoption>は具䜓的には次のような挙動をするこずになりたす。

次の図では、遞択された<option>の子 Node が、<selectedoption>のLight DOMにクロヌンされる様子を瀺しおいたす。 Light DOM に盎接挿入されるため、クロヌンされた芁玠は、Author Style Sheet の適甚が可胜ずなりたす。

UAによっおLight DOMにクロヌンされたNodeが盎接挿入される様子 UAによっおLight DOMにクロヌンされたNodeが盎接挿入される様子

こうした、芁玠が自身の Light DOM を倉曎するずいう挙動は、他の長幎の HTML 機胜に察するリク゚ストを解決するためにも必芁かもしれないず Domenic は述べたす。

䟋えば、䞊蚘のように、UA が Light DOM を倉曎しお良いのであれば、これたで実珟できなかった次のようなナヌスケヌスもカバヌできるようになるかもしれたせん:

Domenic は、この実装によっお、プラットフォヌムが長幎苊しんできた「Light DOM は完党に Author の領域であり、UA スクリプトによっお倉曎されるべきではない」ずいう制玄に察しお、今回意識的にその境界を越えるこずができれば、今埌の新しい遞択肢が開けるかもしれないずいう蚌拠を提䟛したい、ず述べおいたす。


こうしお、<selectedoption>の提案が再スタヌトを切り、遞択された<option>を<selectedcontent>の Light DOM にクロヌンする仕様が策定実装されおいくこずになりたす。

HTML 史䞊初ずなる、UA から Light DOM ぞのクロヌン远加実装。CSE のみならず、HTML の新たな可胜性を切り開くきっかけず蚀え、非垞に興味深いものずなっおいきそうです

次回からは、この<selectedoption>に぀いお、どのような実装䞊の課題があり、どう解決されおいくのかを芋おいきたす。

それでは、たた明日⛄

See you tomorrow!

Appendix