🎄Open UI Advent Calendar: Day 16 / Customizable Select Element Ep.14

2024-12-16

目次

目次

  1. はじめに
  2. Customizable Select Elementの関連仕様
    1. slot属性とbehavior属性使用への疑念
    2. slot属性とbehavior属性使用の廃止へ
    3. Appendix

はじめに

🎄 この記事はOpen UI Advent Calendarの16日目の記事です。

Ep.13では、選択された<option>をクローンして<button>に反映する提案が仕様策定中止になり、<selectmenu>は引き続き、slot属性とbehavior属性を使用してカスタマイズする方針となったことについてお話ししました。 今回は、そんな中で提起された、slot属性とbehavior属性使用への疑念についてお話しします。

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

Customizable Select Elementの関連仕様

slot属性とbehavior属性使用への疑念

innerHTMLのクローンに関する議論が一旦収束し、<selectmenu>では、slot属性とbehavior属性を使用してカスタマイズする方針に固まった後、別Issueとして、Domenincからslot属性とbehavior属性使用への疑念が提示されます。

これは、slot属性とbehavior属性の使用方法がHTMLの慣習に合っていないことを、問題として指摘したものでした。

Domenicは、slot属性と::part()は、ユーザが作成したShadow DOMを扱うために、任意の要素に使用できるように設けられており、ネイティブのHTML要素は、特定の親要素を持ち、子要素や疑似要素を通じてカスタマイズされることが一般的だと述べます。

以下などは、特定の親要素のコンテキストのもと、意味を持つ子要素や擬似要素の例です。

  • <details>のための<summary>
  • <details>のための::marker
  • <select>のための<option><optgroup>
  • <fieldset>のための<legend>
  • <dialog>のための::backdrop
  • <input>のための::placeholder

しかし、behavior属性は、ネイティブのHTML要素のShadow DOMをユーザがスタイルするために設けられているのと、特定の親要素のコンテキスト内(<selectmenu>内)でのみしか意味を持たないにも関わらず、任意の要素に使用できるため、HTMLの慣習に沿っていないと主張しました。

(※ behavior属性がShadow Root内の任意要素に使えるのは、もともと<selectmenu>をカスタマイズするためのpart属性が名前を変えたものだからです。::part()はShadow Root内の任意の要素に使えるので、behavior属性も同じ範囲で使えるようになっています。)

したがって、よりHTMLの慣習に沿った方法、例えば子要素パターンを使用する方法に置き換えることができないかが問われました。


これを受けて、Jarharは、slot属性とbehavior属性を使用しているもの全てを、新しい要素に置き換える提案をしました。

  • <div popover=auto slot=listbox behavior=listbox><listbox>に置き換える。
  • <button slot=button behavior=button><selectmenubutton>のようなものに置き換える。
    • ただし、<button>要素をselectmenuの他の部分で使用したい場合があるため、単に<button>を使用することはできないかもしれない。
  • <span slot=selected-value behavior=selected-value><selectedvalue>に置き換える。
  • <span slot=marker behavior=marker><marker>に置き換えるか、疑似要素で置き換えることを検討する

その後、「HTMLの慣習への準拠とWeb Componentsに慣れていない開発者にとっての利用しやすさを優先するため、新しい要素を定義する主張の Domenic」vs、「ネイティブHTML要素をWeb Componentsを扱う感覚でカスタマイズするという試みを推す Open UI側」での議論が白熱します。

Open UI側の主張:

  • <selectmenu>は、Shadow DOMを持ち、それを扱う方法が明確に定義された最初のネイティブHTML要素になる
  • slotを利用することで、意味的に適切な要素(例えば、<button><input>)を直接使用できる
  • ::part()は、そもそも、Web Components技術を採用しようとしたためにMSで提案された。::part()slotを使用することで、ネイティブHTML要素を使用しながら、Web Componentに触れてもらえるきっかけになる

Domenicの主張:

  • <selectmenu>はShadow DOMを含むべきではない。もし、<input type=date><details>, <select>のように、UA側でShadow Rootを持つように実装されたとしても、これは実装の詳細に過ぎないため、外部向けに公開されるべきではない
    • 重ねて、::part()slotユーザーが作成するShadow DOMの領域に留まるべきであり、ネイティブHTML要素のカスタマイズにこれらを使用するべきではない
  • 意味的に適切な要素は、<selectmenu>が期待する動作をする要素になる
    • 例えば、<button>は任意の動作を持つことができるが、<summary>はそうでばないので、<button>ではなく、<summary>を用いて<details>を展開/折りたたむ動作をする。<selectmenu>とそのボタン(e.g. <selectmenubuton>)も同様の関係を持つべき
  • ::part()slotはShadow DOMを作成したことがない開発者にとって新しい概念になる可能性がある

これら一連の議論を経て、Mason Freedを中心とするOpen UI側は、Domenic側に倒れ、新しい要素を定義する方向で考えがまとまり、一旦IssueをCloseします。(comment)


しかし、このCloseされたIssueには、Web Componentsを活用するという期待が裏切られたことや、CSSの長年の課題に対する解決策としてWeb Componentsの役割が果たされなかったことへの悲痛なコメントが続きます。

e.g. comment

For what it's worth, I'm pretty sad about the conclusion that we're not going to use Web Components technologies to describe pieces of the web that are implemented in browsers. In my mind, this was one of the major goals of Web Components (and thinking that is not a new opinion for me). There was admittedly a very long history leading to Web Components (including HTML Components, XBL 1, RCC, and XBL 2), and I was involved more in some of the earlier parts and had gotten tired of it before the parts that actually succeeded in building the pieces that have become a part of the Web. But being able to describe builtin controls formally was, I think, the main reason I thought that work was important in the first place.

e.g. comment

I presume that you've read this thread and you'll find that that is not desired by at least one editor of the HTML specification. We additionally heard some general push back to this notion during the F2F CSSWG held 1.5 weeks ago. Suffice it to say, it's a lot of paddling upstream for that vision to come to fruition.

話は少し逸れるのですが、筆者は、WHATWG側ですら、標準となって長いWeb Components機能の認知・利用拡大どころか、ユーザランドでの利用には極めて慎重な姿勢だということを、本Issueで感じました。また、Open UIは、やはり「提案」という立ち位置で、その提案が受け入れられるかは、標準化団体の方針に大きく依存することも実感しました。

slot属性とbehavior属性使用の廃止へ

同Issueは、再度Openとなり、slot属性とbehavior属性の使用を廃止することが提案されます。

[select] Don't reuse slot="" and ::part(); behavior="" is also strange · Issue #702 · openui/open-ui
slot="" and ::part() are used for custom elements. They are a separate namespace for authors to use. Native HTML elements get customized via normal child elements and pseudo-elements: <summary> for...
[select] Don't reuse slot="" and ::part(); behavior="" is also strange · Issue #702 · openui/open-ui favicon https://github.com/openui/open-ui/issues/702#issuecomment-1662708138
[select] Don't reuse slot="" and ::part(); behavior="" is also strange · Issue #702 · openui/open-ui
slotとbehavior時代
<selectmenu>
  <div slot=button>
    <span>split button</span>
    <button behavior=button>
      <span behavior=selected-value />
    </button>
  </div>
  <div slot=listbox behavior=listbox popover=auto>
    <option>one</option>
    <option>two</option>
  </div>
</selectmenu>
提案された手法(ボタンは下記3を採用)
<selectmenu>
  <span>split button</span>
  <button type=selectmenu>
    <selectedvalue />
  </button>
  <listbox>
    <option>one</option>
    <option>two</option>
  </listbox>
</selectmenu>
  • 選択された要素
    • <selectedvalue> = slot=selected-value, behavior=selected-value
  • ボタン
    1. <selectmenubuttoncontainer>, <selectmenubutton> = slot=button, behavior=button
    2. <selectmenu>中の最初の<button> = slot=button, behavior=button
    3. <listbox><option>以外の全ての要素, <selectmenubutton>または<button type=selectmenu> = slot=button, behavior=button
  • Listbox
    • <listbox> = slot=listbox, behavior=listbox
    • <datalist> = slot=listbox, behavior=listbox

これをもって、Open UI内で再度話し合われ、<selectmenu>slot属性とbehavior属性の使用を廃止が決定されました。 (※その間にちょうど<selectmenu>から<selectlist>へのRenameがあったため、以下のRESOLVEDとなっています。)

RESOLVED: move forward with the "elements" approach for <selectlist>,abandoning the "slots" approach. Open fresh issues for any new questions. https://github.com/openui/open-ui/issues/702#issuecomment-1664464531

<selectlist>slot属性とbehavior属性の使用が廃止されたことにより、一旦は中止と判断された「選択された<option><button>にクローンしてカスタマイズできるようにする」の結論が揺らぐことになります。

次回は、その後の「選択された<option>の反映とカスタマイズ」についてお話しします。


それでは、また明日⛄

See you tomorrow!

Appendix

Copyright © 2024 saku 🌸 All rights reserved.