🎄Open UI Advent Calendar: Day 12 / Customizable Select Element Ep.10
Published on December 12, 2024
Customizable Select Elementの関連仕様: `appearance: base-select;` - `::picker()`のデフォルト色から深掘る、system-color/ color-scheme/ prefers-color-schemeの関係
Table of Contents
Table of Contents
はじめに
Customizable Select Element Ep.9 から、 appearance: base-select;
で提供される、CSE のデフォルトの見た目が決定された背景の議論をお話ししてきました。
Ep.9では、<option>::checkmark
が現状の見た目となった背景について、Ep.10では、ポップオーバーを開閉するボタン要素右の矢印アイコン::picker-icon
について深掘りました。 今回は、CSE がデフォルトで使用する「色」の関連技術について理解を深めていきます。
2024/12/9時点でのselectの各パーツの定義
Customizable Select Elementの関連仕様
CSE の主に::picker()
部分のデフォルトカラーには<system-color>
が使用されています。
<system-color>
キーワードとは
<system-color>
は、ユーザのカラーテーマ設定やcolor-scheme
によって適用される色が決まるキーワードです。
身近な例として、<textarea>
要素の背景色である「Field」やその文字色である「FieldText」などがあり、多くのシステムカラーが定義されています。
system-colorの例
この<system-color>
にどのような色が適用されるかは、ユーザのカラーテーマ設定やcolor-scheme
によって変化します。
color-scheme
プロパティ
color-scheme
プロパティは、ページ実装者(以下、Author)が設定したカラーテーマを反映できる CSS プロパティです。
<select>
のみならず、多くの Form Control やスクロールバーなどは、歴史的背景から Author によるスタイルが困難なものばかりです。
そうした Author スタイルシートからスタイルが困難な要素が、カラーテーマに対応できるよう、color-scheme
プロパティが存在しています。
While the prefers-color-scheme media feature allows an author to adapt the page’s colors to the user’s preferred color scheme, many parts of the page are not under the author’s control (such as form controls, scrollbars, etc). The color-scheme property allows an element to indicate which color schemes it is designed to be rendered with. These values are negotiated with the user’s preferences, resulting in a used color scheme that affects things such as the default colors of form controls and scrollbars. (See § 2.2 Effects of the Used Color Scheme.) https://drafts.csswg.org/css-color-adjust/#color-scheme-prop
color-scheme
プロパティは次のような値を取ります。
/* OSのライトテーマのみをサポートする */
color-scheme: light;
/* OSのダークテーマのみをサポートする */
color-scheme: dark;
/* 両方サポートする */
color-scheme: light dark;
/* ライトテーマを強制する */
color-scheme: only light;
/* ダークテーマを強制する */
color-scheme: only dark;
/* ページデフォルトのカラーテーマを使用する */
color-scheme: normal;
@media(prefers-color-scheme: <light | dark>)
color-scheme
で Author が設定したカラーテーマを反映できるのに対し、@media(prefers-color-scheme: <light | dark>)
を使用すると、ユーザが設定したカラーテーマを、prefers-color-scheme
を用いてページに反映することができます。
The prefers-color-scheme media feature reflects the user’s desire that the page use a light or dark color theme. https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme
例えば、Mac のシステム設定などで、OS にユーザが設定したカラーテーマがダークテーマだった場合、@media(prefers-color-scheme: dark)
中に記述した、ダークテーマの CSS が適用されます。
@media (prefers-color-scheme: light) {
:root {
color: var(--light);
background-color: var(--light-bg);
}
}
@media (prefers-color-scheme: dark) {
:root {
color: var(--dark);
background-color: var(--dar-bg);
}
}
このように、prefers-color-scheme
Media Query を用いると、ユーザがブラウザや OS に適用したカラーテーマを、コンテンツに反映することができます。反映させるのはあくまで Author で、 Author がprefers-color-scheme
を CSS でクエリして、そこにスタイルをあてて始めてコンテンツに反映されます。ユーザがカラーテーマ変えたからといって、Media Query にスタイルが当たっていなければ、ページのスタイルが変わるとは限りません。
color-scheme
は、Author が要素やページ自体に対して、対応しているカラーテーマを宣言するプロパティです。例えば、ユーザが OS にはダークテーマを設定してる場合に、Author がページに Dark/Light 切り替え機能を用意して、color-scheme: light
を設定すれば全体を light に、color-scheme: dark
を設定すれば全体を dark にすることができます。
カラースキーマの計算方法
ユーザは、Chrome の Automatic Dark Mode を用いて、Color Scheme を変更することができます。
color-scheme
は Author が適用する色を決める CSS プロパティですが、ユーザが Color Scheme を変更する設定していた場合、実際に適用される色はどのようにして決まるのでしょうか?
To determine the used color scheme of an element:
If the user’s preferred color scheme, as indicated by the prefers-color-scheme media feature, is present among the listed color schemes, and is supported by the user agent, that’s the element’s used color scheme.
Otherwise, if the user has indicated an overriding preference for their chosen color scheme, and the only keyword is not present in color-scheme for the element, the user agent must override the color scheme with the user’s preferred color scheme. See § 2.3 Overriding the Color Scheme.
Otherwise, if the user agent supports at least one of the listed color schemes, the used color scheme is the first supported color scheme in the list.
Otherwise, the used color scheme is the browser default. (Same as normal.) https://drafts.csswg.org/css-color-adjust/#color-scheme-prop
つまり、次の順番でどのような色が適用されるか決まります。
- ユーザの設定した色が
color-scheme
によってサポートされる場合:ユーザの設定した Color Scheme が適用される - そうでない場合、つまり
color-scheme
で「only」を使用せずに「light/dark」が適用されている場合:ユーザの設定した Color Scheme で上書き適用される - そうでない場合、つまり
color-scheme
に「only」を使用して「light/dark」が適用されている場合:color-scheme
の色が適用され、ユーザの設定した Color Scheme では上書きできない - 上記いずれでもない場合:
color-scheme: normal;
の色が適用される。ページデフォルトの色が<meta name="color-scheme" content=<"dark" | "light">
で指定されている場合はその色が適用され、指定されていない場合はページデフォルトの色(通常はライトテーマ)が適用される
light-dark()
関数
2024 年の CSS 新機能として登場した、light-dark()
関数は、@media(prefers-color-scheme: <light | dark>)
を使用せずとも、color-scheme
を要素に反映することができる CSS 関数です。
:root {
color: light-dark(var(--light), var(--dark));
background-color: light-dark(var(--light-bg), var(--dark-bg));
}
color-scheme
のテーマに依存した色の変更は、ブラウザが UA スタイルシートに定義している<system-color>
の利用でのみ可能でしたが、light-dark()
関数の登場により、Author の定義した色がcolor-scheme
プロパティのテーマに依存して変更可能になりました。
System colors have the ability to react to the current used color-scheme value. The light-dark() function exposes the same capability to authors.
light-dark()
関数は、color-scheme
がライトテーマか不明な場合は第一引数の<color>
値を、ダークテーマの場合は第二引数の<color>
値を適用します。
上記で理解した、カラースキーマの適用順序をlight-dark()
関数で確認できるデモを作成しました。長いので Copepen リンクのみ記載します。
デモ:
See the Pen which colour scheme? - light-dark() by saku (@sakupi01) on CodePen.
このように、<system-color>
キーワードを使用すると、ユーザのカラーテーマ設定やcolor-scheme
の値を反映した色でレンダリングされ、UA スタイルシート外部の設定と調和を保てます。この目的のために、<system-color>
は定義(あるいは、既存実装から共通化して仕様化)され、UA スタイルシートで利用されているのです。
ボタン要素や::picker()
の色
そういうわけで、CSE の::picker()
の色には、<system-color>
を使用することに決まりました。
::picker(select) {
/* Same properties as popover and dialog */
color: CanvasText;
background-color: Canvas;
border: 1px solid;
}
/* https://github.com/w3c/csswg-drafts/issues/10857 */
加えて、ボタン部分を表す、<select>
の色に関しては、次の議論の結果、<select>
には透明なbackground-color
を使用し、color
, border-color
は親要素から継承するという決定がなされました。
RESOLVED: Use currentColor for borders, inherit the color, transparent background color (for in-page controls). Use system colors for pickers. https://github.com/w3c/csswg-drafts/issues/10909#issuecomment-2491769385
今回はそこまで追えなかったのですが、<select>
の各状態に応じたスタイルも議論されており、現状は次のような<select>
のスタイルが提案されています。
select {
border: 1px solid currentColor;
background-color: transparent;
color: inherit;
}
select:enabled:hover {
background-color: color-mix(in lab, currentColor 10%, transparent);
}
select:enabled:active {
background-color: color-mix(in lab, currentColor 20%, transparent);
}
select:disabled {
color: color-mix(in srgb, currentColor 50%, transparent);
}
select option:enabled:hover {
background-color: color-mix(in lab, currentColor 10%, transparent);
}
select option:enabled:active {
background-color: color-mix(in lab, currentColor 20%, transparent);
}
select option:disabled {
color: color-mix(in lab, currentColor 50%, transparent);
}
/* https://github.com/w3c/csswg-drafts/issues/10909#issuecomment-2491769385 */
今回は、ボタン要素や選択肢ポップオーバーの「色」に関して取り上げました。
-
appearance: base-select;
の見た目は、どのようにして決まったのか- 選択された
<option>
のデフォルトチェックマーク - ポップオーバーを開閉するボタン要素右の矢印アイコン
- ボタン要素や選択肢ポップオーバーの色
-
その他のスタイル
- 選択された
その他のスタイルについては、現時点では不確定要素が多いため、今後確定してきた段階で調査していきたいと思います。
appearance: base-select;
に関して、今回紹介した以外の、現状検討されているその他スタイルに関しては、こちらのIssueを参照ください。
それでは、また明日⛄
See you tomorrow!