<button>とかのスタイルを消して書き直すときに考えることの備忘録
all: unset;
などを使ってUAスタイルシートを消してまっさらな場所からスタイルを当てるのは気持ちがいいですが、アクセシビリティ等の観点から重要な分岐が見落とされる可能性があります。
ここではChromeのUAスタイルシートを参考に、検討しておいたほうがいい状態をいくつかリストします。
(もちろん、既存のUIコンポーネントライブラリの使用が可能であれば、それが最も堅牢な選択肢でしょう。)
参考
UAスタイルの中には、CSSのカスケードルールの範疇で実装されているものもあれば、レンダリングエンジンの特別処理として書かれていて作者スタイルシートでの上書きが不可能なものもあります。これはブラウザ実装により異なります。
スコープ
UIコンポーネントを作るような場面を想定しています。したがって、要素名自体は固定として、その中で見落としがちな分岐をリストアップします。
display: block;
や box-sizing: border-box;
をはじめとして、静的なデザインを適用する時点で必要になることが明らかなものはここには書きません。
<input>
は実質的に <input type="...">
の値ごとに別種の要素であるとみなします。
本記事の目標は、見落としを防いでinformed decisionをすることにあります。想定する品質ラインは、Webブラウザのデフォルト挙動と同等程度です。 (それ以上の使いやすさを考えるのは本記事のスコープ外です)
カーソル
- UAスタイルシートでは、
<label>
,<select>
およびボタン類のフォームコントロールにはcursor: default;
がついている。- テキストが
cursor: text;
相当になるのを抑止して、クリック動作を示すため。 - テキスト類のフォームコントロールは
<label>
のcursorを継承してくることがあるため、これをcursor: auto;
にリセットしている。
- テキストが
- UAスタイルシートでは、ボタン類のフォームコントロールには
user-select: none;
がついている。 - UAスタイルシートでは、テキスト類のフォームコントロールには
user-select: text;
がついている。- UAスタイルシートの範囲内では、これはデフォルト値である
auto
と同等の挙動のはずです。祖先コンポーネントでuser-select
が上書きされている場合にテキスト入力の動作が意図せず変わってしまわないように明示しているのでしょう。
- UAスタイルシートの範囲内では、これはデフォルト値である
- UAスタイルシートでは、テキスト類のフォームコントロールには
unicode-bidi: plaintext;
がついている。
擬似クラス / 属性セレクタ
擬似クラスや属性による条件分岐を見落とすと、UAで当てられていた必要なスタイルが削除されてしまい、アクセシビリティ等の観点から問題が発生する可能性があります。
- テキスト類のフォームコントロール (
<input type="text">
,<input type="search">
etc.)-
:focus
または:focus-visible
... キーボード操作時等のフォーカス表示 -
:enabled
または:disabled
... フォームコントロールが利用不可能であることを視覚的に表示 -
:autofill
... オートフィルが発生した場合。(ChromeやSafariでは!important
がついていてどの道上書きされません)
-
- ボタン類のフォームコントロール
-
:focus
または:focus-visible
... キーボード操作時等のフォーカス表示 -
:enabled
,:disabled
, または[disabled]
... フォームコントロールが利用不可能であることを視覚的に表示 -
:active
... ユーザーによるボタン押下に反応- テキスト類でも利用可能だが、UAスタイルシートではあまり使われていない
-
- リンク
-
:any-link
または[href]
... 実際にリンクになっているかどうかを確認してスタイルを当てるのが望ましい -
:focus
または:focus-visible
... キーボード操作時等のフォーカス表示 -
:enabled
または:disabled
... フォームコントロールが利用不可能であることを視覚的に表示 -
:active
... ユーザーによるボタン押下に反応 -
:link
または:visited
- WebKit/Blinkではこの擬似クラスを使わず、
color: -webkit-link;
を指定することで暗黙的に同じ効果を達成している
- WebKit/Blinkではこの擬似クラスを使わず、
-
- チェックボックス
- フォーカス、有効状態、アクティブについては上記を参照
-
:checked
... 状態特有のスタイルを当てる場合は、:indeterminate
状態も考慮が必要。
- ダイアログ (
<dialog>
)-
:open
,:close
, または[open]
... 閉じている場合はdisplay: none;
にする必要がある-
<details>
でも同様の考慮が必要だが、これはレンダリングエンジンの特殊実装になっていることが多そう
-
-
:modal
... モーダルかどうかによって表示を変えることが期待されている
-
- その他のフォーカス可能な要素 (フォームコントロール内の補助的なウィジェット、
<dialog>
,<iframe>
, スクロール可能な要素、またはtabindexが設定されている場合など)-
:focus
または:focus-visible
... キーボード操作時のフォーカス表示
-
意外なことに、以下の擬似クラスはUAスタイルシートではあまり使われていません。
-
:hover
- サイトによっては、マウスポインタが上にあるときにはボタンを強調するなどのスタイルを当てることがあります。
-
[readonly]
,:read-only
または:read-write
- enabled/disabled とは別の概念です。
- 入力不可能であることを視覚的に表示することが可能です。
擬似要素
擬似要素のスタイルはオリジナル要素のスタイルとは独立にカスケードするため、必要な処理を怠るとUAのスタイルが残ったままになってしまいます。
Tree-abiding
複雑なフォームコントロールや <video>
要素などは内部にシャドウ要素を含んでおり、これらにはブラウザ固有の擬似要素でアクセスできることがあります。 (例: ::-webkit-clear-button
) こういったもののうち、ベンダープレフィックスが必要な擬似要素については扱わないことにします。
-
::placeholder
- テキスト系のフォームコントロールなどで発生します。これらのコントロールのスタイルを設定するなら、一緒に設定しておくといいでしょう。
-
color
を設定するのが一般的でしょう。
-
::before
,::after
-
<q>
など一部の要素で使われていることがあるので、必要に応じて上書きするといいでしょう。 -
:before
,:after
と書かれていることもあります。
-
-
::marker
-
display: list-item
のときだけ発生するので、通常は注意する必要はありません。
-
-
::file-selector-button
- フォームコントロールのシャドウ要素のなかでは珍しく、標準的な擬似要素でアクセスできます。
-
::backdrop
- ダイアログで使われます。
ハイライト
これらはページ全体のテーマの一部として設定されることが多いでしょう。
::selection
::target-text
::spelling-error
::grammar-error
強制スタイル
UAスタイルシートには !important
がついているものもあります。これらはオリジン優先度の関係で作者スタイルシートからは上書きできません。これらのスタイルが強制されていてもなるべく問題がないようにスタイルを当てるのがよいでしょう。
ここではブラウザやスペックの記述から発見された候補を列挙していますが、これらが常に !important
であるとは限りません。ベンダープレフィックスのあるものは原則として除いています。
- いくつかの
display: none;
指定はレンダリングエンジンに組み込みのルールとして実装されていることがあります。 - フォームコントロールの横書き強制
-
::placeholder
のuser-events: none
-
<input type="file">
のtext-align: start
-
:autofill
のcolor
およびbackground
-
<select>
のoverflow: visible
-
<input>
のoverflow: clip
,overflow-clip-margin: 0
タグ固有のボックス
<a>
と <button>
の両方に使えるスタイルを作る場合などには、特定のタグでのみ発生するボックス構造に注意が必要です。
- 一部のボタン系のフォームコントロールではボタンの内容物のための匿名ボックスが生成されます。flex系またはgrid系の
display
値を設定することでこのボックスの生成を回避することができます。 -
<fieldset>
にはfieldsetの内容物のための匿名ボックスが生成されます。
メディア特性
UIの状態を示すために視覚効果を使うのは重要なことですが、それをなるべく多くの環境で効果的に適用するにはメディア特性も考慮するといいでしょう。
Webブラウザのデフォルトのウィジェットを使う限りにおいてはブラウザがある程度考慮してくれることもありますが、それを上書きする場合は考慮漏れのリスクが多少あります。
-
色の表示に関する特性
-
monochrome
やinverted-colors
は考慮に値するでしょう。 - 閲覧者の色覚特性もさまざまであるため、そもそも明度だけである程度の判別ができるのが望ましいという話もあります。
-
- ポインタやその精度に関する特性。フォームコントロールの大きさなどに考慮の余地あり。
- 表示に関するユーザーの希望。ダークモード、ハイコントラストモードや動きの削減など。
Discussion