🎄Open UI Advent Calendar: Day 10 / Customizable Select Element Ep.8
Published on December 10, 2024
Customizable Select Elementの関連仕様: `appearance: base-select;` - 選択された`<option>`のデフォルトチェックマークのスタイルはどうやって決まったのか
Table of Contents
Table of Contents
はじめに
Customizable Select Element Ep.8では、<selectmenu>
を経て、<selectlist>
から<select>
に至るまでの経緯をお話ししました。
端的にまとめると、初期 Explainer で使用されていた<selectmenu>
は、主に UI パターンの観点から混乱を招くことが懸念され、Open UI 内での議論を以って<selectlist>
に変更されました。
その後、<selectlist>
の実装の方針や Progressive Enhancement の観点から、<select>
の機能を拡張する形で実装した方が良いのではないかという議論が行われ、2024/9 月に<select>
として RFC が発表されるに至ります。

Customizable Select Elementの関連仕様
各パーツの定義
CSE の各パーツは、RFC が出された時点から大きく変化しています。 (2024/12/9 現在)
2024/12/9時点でのselectの各パーツの定義
<button>
: 選択肢のポップオーバーを開閉するボタン要素::picker-icon
: ボタン要素右の矢印アイコン<selectedcontent>
: 選択されている Option の内部 HTML のクローンを作成する要素::picker(select)
:<select>
内の<button>
以外の要素を含むポップオーバー部分<option>
: 選択肢の要素option::checkmark
: 選択されている Option を示すチェックマーク部分<option>:checked
: 選択されている Option を示す擬似クラス
appearance: base-select;
<select>
を CSE に Opt-in するには、CSSappearance
プロパティを使用します。次のように、<select>
と::picker(select)
にappearance: base-select;
を指定することで、<select>
を CSE にアップグレードすることができます。
select, ::picker(select) {
appearance: base-select;
}
<select>
<option>Option 1</option>
<option>Option 2</option>
<option>Option 3</option>
</select>
上記の HTML と CSS で、CSE が Opt-in され、<select>
がCSEデフォルトのスタイルになります。
CSEデフォルトのスタイル
ここで気になるのが、「何を以てこのデフォルトのスタイルになったのか」です。
選択された<option>
のチェックマーク
CSE デフォルトのスタイルでは、選択された<option>
にチェックマークがついています。チェックマークは、CSE でなくても(appearance: base-select;
を設定しない<select>
でも)ついていますが、CSE のデフォルトスタイルを決める段階では、「チェックマークが必要か」「どういった実装にするべきか」という議論が行われました。
まず、「チェックマークが必要か」に関してです。
チェックマークを提供しないことになった場合、コントラスト比の観点からアクセシビリティの問題が生じる可能性があるとの指摘がありました。
チェックマークがなく、選択肢ポップオーバーの背景色とポップオーバー内部の背景色のコントラスト比が低い場合、選択された要素を明示するために非常に強い色の背景色をつけるなどの対策が必要になります。そうなった場合、フォーカスインジケータとのコントラスト比が低くなる可能性が出てきます。
つまり、「チェックマークを提供しない」という選択肢をとった場合、「選択肢ポップオーバーの背景色 vs ポップオーバー内部の背景色 vs フォーカスインジケータのボーダー色」という3つの色のコントラスト比のバランスを考慮する必要があるということになります。 その点、チェックマークを提供すると、選択された要素を明示することができるため、選択肢ポップオーバーの背景色とポップオーバー内部の背景色のコントラスト比を気にする必要がなくなり、幾分かコントラスト比の考慮が緩和されるということです。
加えて、単一選択<select>
の時点で、チェックマークを考慮しておくと、チェックマークの提供が必ず必要になってくる複数選択<select>
の実装においても役立つという理由がありました。
次に、「どういった実装にするべきか」に関して追っていきます。 チェックマークをどのように UA スタイルシートに実装するかに関して、Issueの時点では次のように実装されることが望ましいとされました。
option::marker {
content: '\2713' / '';
}
option:not(:checked)::marker {
visibility: hidden; /* visibility: hiddenにすることで幅を保てる */
}
チェックマークが擬似要素で実装されているのは、DOM にチェックマークを実装するのではなく、CSS 擬似要素で実装することで、ユーザがより簡単に上書きや削除する(カスタマイズする)ことが可能だからです。
擬似要素と言っても、::before
や::after
は更なるスタイリングを施すために用いたいというケースも考えられるため、新しい擬似要素が定義されることになりました。
RESOLVED: create new pseudo elements for checkmark and dropdown icon for base appearance select instead of using ::before and ::after in the UA stylesheet https://github.com/w3c/csswg-drafts/issues/10908#issuecomment-2371836734
その上で、次に注目すべき点は、擬似要素のcontent
が'\2713' / ''
となっていることです。
筆者は知らなかったのですが、content
プロパティはスラッシュ(/
)区切りで alt テキストを指定することができ、これが明示してある場合は、content
プロパティの前半が表示され、後半は alt テキストとして AT に読み上げられるようです。(ブラウザによって alt テキストは表示もされるそうですが、未確認です)
上記の実装により、AT はcontent
プロパティによる読み上げをせず、選択された<option>
の checked 属性による読み上げのみしてくれるので、重複した読み上げが起こりません。
加えて、絵文字の「✔︎」などを使用するのではなく、標準化された Unicode でチェックマークを表現することにより、OS の慣習に追従した、一貫性のある表示を実現できます。
RESOLVED: support checkmark next to checked option, implemented via the content property on the ::marker pseudo element. The UA should set a Unicode character by default, which isn’t read out by screen reader. https://github.com/openui/open-ui/issues/863#issuecomment-2127775634
上記の議論時点では::marker
でしたが、一旦 Chromium には付け焼き刃的に::before
で実装され、RFC 公開時点ではそのまま::before
で、2024/12 現在では::checkmark
に変わり、次の UA スタイルシートが実装されています。
RESOLVED: Name the pseudo-element ::checkmark https://github.com/w3c/csswg-drafts/issues/10908#issuecomment-2489173316
select option::checkmark {
content: '\2713' / '';
}
select option:not(:checked)::checkmark {
visibility: hidden;
}
select::picker-icon {
/* margin-inline-start pushes the icon to the right of the box */
margin-inline-start: auto;
display: block;
content: counter(fake-counter-name, disclosure-open);
}
chrome canaryで
::checkmark
のUAスタイル
CSE のデフォルトスタイルに関しては、次の Issue で現在進行形で更新が重ねられており、Chromium ではこの Issue の変更に追従する形で実装が進められているようでした。
Issue によると主に次の項目に着目できそうで、今回はその一部であるチェックマークに関して取り上げました。
-
appearance: base-select;
の見た目は、どのようにして決まったのか- 選択された
<option>
のデフォルトチェックマーク - ポップオーバーを開閉するボタン要素右の矢印アイコン
- ボタン要素や選択肢ポップオーバーの色
- その他のスタイル
- 選択された
上記 Issue に記されているデフォルトスタイルになった背景について、次回からも引き続き見ていこうと思います。
それでは、また明日⛄
See you tomorrow!