all: unset;
などを使ってUAスタイルシートを消してまっさらな場所からスタイルを当てるのは気持ちがいいですが、アクセシビリティ等の観点から重要な分岐が見落とされる可能性があります。
ここではChromeのUAスタイルシートを参考に、検討しておいたほうがいい状態をいくつかリストします。
(もちろん、既存のUIコンポーネントライブラリの使用が可能であれば、それが最も堅牢な選択肢でしょう。)
UAスタイルの中には、CSSのカスケードルールの範疇で実装されているものもあれば、レンダリングエンジンの特別処理として書かれていて作者スタイルシートでの上書きが不可能なものもあります。これはブラウザ実装により異なります。
UIコンポーネントを作るような場面を想定しています。したがって、要素名自体は固定として、その中で見落としがちな分岐をリストアップします。
display: block;
やbox-sizing: border-box;
をはじめとして、静的なデザインを適用する時点で必要になることが明らかなものはここには書きません。
<input>
は実質的に<input type="...">
の値ごとに別種の要素であるとみなします。
本記事の目標は、見落としを防いでinformed decisionをすることにあります。想定する品質ラインは、Webブラウザのデフォルト挙動と同等程度です。 (それ以上の使いやすさを考えるのは本記事のスコープ外です)
<label>
,<select>
およびボタン類のフォームコントロールにはcursor: default;
がついている。cursor: text;
相当になるのを抑止して、クリック動作を示すため。<label>
のcursorを継承してくることがあるため、これをcursor: auto;
にリセットしている。user-select: none;
がついている。user-select: text;
がついている。auto
と同等の挙動のはずです。祖先コンポーネントでuser-select
が上書きされている場合にテキスト入力の動作が意図せず変わってしまわないように明示しているのでしょう。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
... ユーザーによるボタン押下に反応:any-link
または[href]
... 実際にリンクになっているかどうかを確認してスタイルを当てるのが望ましい:focus
または:focus-visible
... キーボード操作時等のフォーカス表示:enabled
または:disabled
... フォームコントロールが利用不可能であることを視覚的に表示:active
... ユーザーによるボタン押下に反応:link
または:visited
color: -webkit-link;
を指定することで暗黙的に同じ効果を達成している:checked
... 状態特有のスタイルを当てる場合は、:indeterminate
状態も考慮が必要。<dialog>
):open
,:close
, または[open]
... 閉じている場合はdisplay: none;
にする必要がある<details>
でも同様の考慮が必要だが、これはレンダリングエンジンの特殊実装になっていることが多そう:modal
... モーダルかどうかによって表示を変えることが期待されている<dialog>
,<iframe>
, スクロール可能な要素、またはtabindexが設定されている場合など):focus
または:focus-visible
... キーボード操作時のフォーカス表示意外なことに、以下の擬似クラスはUAスタイルシートではあまり使われていません。
:hover
[readonly]
,:read-only
または:read-write
擬似要素のスタイルはオリジナル要素のスタイルとは独立にカスケードするため、必要な処理を怠るとUAのスタイルが残ったままになってしまいます。
複雑なフォームコントロールや<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>
の両方に使えるスタイルを作る場合などには、特定のタグでのみ発生するボックス構造に注意が必要です。
display
値を設定することでこのボックスの生成を回避することができます。<fieldset>
にはfieldsetの内容物のための匿名ボックスが生成されます。UIの状態を示すために視覚効果を使うのは重要なことですが、それをなるべく多くの環境で効果的に適用するにはメディア特性も考慮するといいでしょう。
Webブラウザのデフォルトのウィジェットを使う限りにおいてはブラウザがある程度考慮してくれることもありますが、それを上書きする場合は考慮漏れのリスクが多少あります。
monochrome
やinverted-colors
は考慮に値するでしょう。バッジを受け取った著者にはZennから現金やAmazonギフトカードが還元されます。