背景色を前景色として扱う場合はシステムカラーをフォールバックする

広告
背景色を前景色として利用する場面は少なくありません。例えば、疑似要素を用いて装飾を施す際に mask-image
や clip-path
プロパティで特定の図形を描画する場合、背景色として前景色(文字色)を指定することがあります。
.Button { /* ... */
&::after { content: ""; mask-image: var(--icon-chevron-rightward); mask-repeat: no-repeat; mask-position: center; mask-size: contain; inline-size: 1em; aspect-ratio: 1; background-color: currentColor; }}
上記のような実装はよく見かける手法ですが、この実装はアクセシビリティ的な問題を孕んでいます。
それは「強制カラーモード」下での挙動であり、background-color
は強制カラーモード下では明示されたシステムカラー以外はブラウザで指定された値に強制的に上書きされてしまう点です。
つまり、上記のような実装では強制カラーモード下ではボタンの背景色もろとも同一のシステムカラーに置き換えられるため、mask-image
で設定したアイコンは消失してしまいます。
あくまで「装飾」的なものであればそこまで問題にはならないかもしれませんが、チェックボックスやラジオボタン、アイコンのみのリンクなどで背景色を前景色として使用するケースも存在し、その場合は強制カラーモード下では可視化されず利用できなくなります。これに関してはアクセシビリティを強みとしている制作会社のWebサイトでも見受けられ、強制カラーモード下で導線が消失しているのを見かけたことがあります。
このような問題に対処するために、前景色を前景色として扱う場合は強制カラーモード用のフォールバックを用意すると良いでしょう。先述したようにbackground-color
は明示されたシステムカラー以外は上書きされるため、フォールバックにシステムカラーを定義すれば解決できるということです。
結論
background-color
にシステムカラーをフォールバックする場合は、次のようにカスタムプロパティを経由するのが効率的です。
* ======================================================// MARK: background-current//// 強制カラーモード下ではシステムカラーに置き換える視認可能な背景色として使用するカスタムプロパティを定義します。// 主に `currentColor` を指定した `background-color` を前景色として使用する場合に利用します。// 疑似要素などで背景色を前景色として扱う際に指定してください。// ====================================================== */:root { --background-current: currentColor;}
@media (forced-colors: active) { :root { --background-current: CanvasText; }
:where(:any-link) { --background-current: LinkText; }
:where(button:enabled) { --background-current: ButtonText; }
:where(:disabled) { --background-current: GrayText; }}
.Button { /* ... */
&::after { content: ""; mask-image: var(--icon-chevron-rightward); mask-repeat: no-repeat; mask-position: center; mask-size: contain; inline-size: 1em; aspect-ratio: 1; background-color: var(--background-current); }}
デフォルトでは currentColor
を定義して現在の color
の値と同じようになるように設定し、強制カラーモード下では forced-colors: active
メディア特性でコンテキストに応じたシステムカラーへ上書きを行います。
背景色を前景色として扱う場合はこのカスタムプロパティを使用するように強制することで、強制カラーモード下での消失を抑えることが可能になります。
強制カラーモード対応を行う意義
そもそも強制カラーモードを利用する人ってどれくらいいるの?と思われるかもしれません。これに関しては以下の記事の説明が参考になります。
High contrast mode is useful for many different people and includes people with low vision, color blindness, people prone to migraines or light sensitivity and people prone to overstimulation.
But also people who know of the feature and use it to keep their screen readable in bright sunlight, or dim their entire UI in dark environments. High contrast mode is one of the only features that will force all colors to change, and guarantees that across the operating system UI and browser (compared to say, prefers-dark-mode, which only works for sites that have it implemented).
In terms of numbers, Microsoft states that 4% of Windows users use High Contrast mode. In the WebAIM low vision survey, 50% of low vision users indicate they used the mode but of course, that is likely a very self-selecting group of savvy users.
- 強制カラーモードは低視力、色覚異常、片頭痛や光過敏症、過度の刺激に弱い人々だけでなく、明るい日差しの下で画面を見やすくしたり、暗い環境でUI全体の明るさを落としたりするために使用する人もいる。
- Microsoftのデータによると、Windowsユーザーの4%がハイコントラストモードを使用しており、WebAIMの低視力調査では、低視力ユーザーの50%がこのモードを使用していると回答している。
- 訪問者の25人に1人がこのモードを有効にしている可能性があると推測できる。
強制カラーモードを利用しているユーザーは想像している以上に多いと分かります。
強制カラーモードの代表格は Windows の 設定 → アクセシビリティ → コントラストテーマ で設定されるハイコントラストモードですが、近年ではブラウザも強制カラーモードを用いた設定を導入し始めていることを覚えておいた方が良いでしょう。
具体的にはEdge 130 から登場したページカラー設定とFirefox 138 から登場したコントラスト制御が該当します。
これらのモードの適用時は強制カラーモードと同じ挙動が設定されます。つまり、background-color
はシステムカラー以外、ブラウザで指定された値に強制的に上書きされることには注意したほうが良いです。
Edge に続き Firefox でもコントラストに応じた配色設定が追加されたということは、そのうち Chrome にも来るかもしれませんね?
強制カラーモードの影響を受けるCSS
強制カラーモード影響を受けるプロパティについてはMDNで一覧化されています。
配色が強制的に上書きされるもの
color
background-color
text-decoration-color
text-emphasis-color
border-color
outline-color
column-rule-color
-webkit-tap-highlight-color
- SVG
fill
属性 - SVG
stroke
属性
特別な動作をするプロパティ
box-shadow
はnone
に強制されるtext-shadow
はnone
に強制されるbackground-image
は URL ベースでない値ではnone
に強制されるcolor-scheme
はlight dark
に強制されるscrollbar-color
はauto
に強制される
background-color
は先述した通り、background-image
は URL ベースでない値では none
に強制されるため、背景色を前景色として扱う以外にも注意が必要です。
例えばカレント表示を background-color
のみで判別する実装を見かけますが、強制カラーモード下では消失するので判別ができなくなります。透明の border
を下線とするなどしてフォールバックしておくと良いかもれません。
border-color
は強制カラーモード下ではシステムカラーへ上書きされるため、transparent
で視覚的に見えない枠線を設定している場合に可視化されます。現在ではあまり見かけませんが、三角形をCSSで描写する際にborder
の仕様を利用して描くテクニックがあります。それらは強制カラーモード下では四角形になるので注意してください。
逆を言えば枠線の無いボタンを実装する際は、border: 1px solid transparent
を指定しておくことで、強制カラーモード下で背景色の消失によるクリッカブルエリアの判別不能を抑制できるということでもあります。
また、box-shadow
も枠線の描写に利用したり、フォーカスリングを目立たせるために outline
の代わりに用いる実装を見かけます。その場合に box-shadow
の消失で問題が起こり得ることは覚えておきましょう。
他にも scrollbar-color
も気をつけておきたく、強制カラーモードが有効な場合にスクロールバーのスタイリングを行うとスクロールバー自体が表示されなくなるリスクがあります。forced-colors: none
メディア特性の中でスタイリングを行うなど、対策は忘れないようにしてください。
画像で実装する際の注意点
そもそも mask-image
を使わずともアイコンは img
や svg
で実装すれば良くない?と感じる人もいるかもしれません。原則的に装飾ではなく意味のあるアイコンは代替テキストを用意した画像で用意するのが筋であり、それらを優先して使うのがベターでしょう。
だからと言って画像で実装すれば問題ないかと言われるとそうではないです。
img 要素で実装する場合の注意点
画像は強制カラーモードの影響を受けないことに注意した方が良いです。強制カラーモード下では color-scheme
が light dark
に強制されるため、暗い画像はダークモード下で、明るい画像はライトモード下で背景色と同化して見えなくなるリスクが存在します。
picture
要素の media
属性で出し分けできるのが理想ですが、コスト的に用意できない場合もあるでしょう。
単色の画像であれば filter
プロパティで白or黒に塗りつぶすことができるので、それで対応しても良いかもしれません。
.Icon { @media (forced-colors: active) and (prefers-color-scheme: dark) { filter: brightness(0) invert(1); /* 白色に塗りつぶす */ }
@media (forced-colors: active) and (prefers-color-scheme: light) { filter: brightness(0); /* 黒色に塗りつぶす */ }}
SVG 要素で実装する場合の注意点
インラインSVGで実装する場合は、それらがどこで使用されているか(テキスト内、リンク内、またはボタン内)を確認し、SVGの使用例に一致するものを選択するようにします。currentColor
は Firefox 138 のコントラスト設定など、環境によってはシステムカラーに置き換えられないので注意が必要です。
@media (forced-colors: active) { :where(svg) { --_svg-foreground: CanvasText;
stroke: var(--_svg-foreground) !important;
& [fill]:not([fill="none"]) { fill: var(--_svg-foreground) !important; }
&:is(:any-link &) { --_svg-foreground: LinkText; }
&:is(button:enabled &) { --_svg-foreground: ButtonText; }
&:is(:disabled &) { --_svg-foreground: GrayText; } }}
色反転モードへの配慮について
macOSやiOSなどのAppleのOSに搭載されているスマート反転モード(OS全体の色をネガポジ反転する)も同様に画像や動画は反転されない挙動を取ります。
そのため、img
要素で実装したアイコンは inverted-colors: inverted
メディア特性と filter: invert(0)
で反転させるのが良いのですが、手元のiOSでは反転されないものの、macOS 15.4.1 では反転されました。こちらに関しては調査中とさせてください。
終わりに
強制カラーモードは、一部のユーザーにとってはウェブサイトを快適に利用するための不可欠な機能です。ブラウザ側でのコントラスト調整機能の拡充が進んでいる現状を鑑みると、より多くのユーザーが同様の表示環境でウェブサイトを閲覧する可能性が高まっています。
すべてのユーザーが情報にアクセスしやすく、快適に利用できるウェブサイトを提供するために、強制カラーモードへの対応は今後ますます重要になるでしょう。強制カラーモード対応に掛かるコストは少なくありませんが、background-color
のフォールバックくらいなら意識を怠らないようにすればコストは掛からないと思うので、できるところからやっていけばいいかなと思います。