👁️

アクセシビリティを気にし出したエンジニアへ、強制カラーモードの紹介

2024/12/10に公開

この記事は、アクセシビリティ Advent Calendar 2024 - Adventar の10日目の記事です。

初めまして、たじまん です。zennのブログ投稿デビューします。
私はとある会社でアクセシビリティエンジニアという名前で、プロダクトチームのイネイブリングなどをするお仕事をしています。

このブログを書くことになったきっかけ

昨今のwebフロントエンド界隈では、コントラスト比やフォームコントロールのアクセシビリティネームをきちんと設定したりと当たり前品質が高まっている気がします。いろんな人がサービスを作る時の指針に「使えるの範囲の広さ」を入れていることが嬉しいです。

そこで、そういったアクセシビリティちょっと気にし始めましたというエンジニアへむけて「強制カラーモード」という使い方があることを紹介したいと思います。

強制カラーモードとは?

強制カラーモードとは、色のコントラストによってテキストの読みやすさを向上させることを目的としたアクセシビリティ機能です。強制カラーモードをオンにすることで、ユーザーエージェントはユーザーまたはOSが指定した色でWebサイトを強制的に上書きします。

上書きにははカラーテーマ(prefers-color-scheme)+強制カラーモードか否かという2軸があり、ダークモードの強制カラーの色とライトモードの強制カラーの色があります。詳しくは 3. Forced Color Palettes - CSS Color Adjustment Module Level 1 をご覧ください。

強制カラーモードの具体例としてはWindowsのハイコントラストモードがあります。

Windowsのハイコントラストの設定画面。設定前

Windowsでハイコントラストを設定した場合の見え方の例

強制カラーモードを設定すると、このように文字やコントロール要素のコントラストが高くなります。(画像は FMV Q&A - [Windows 10] ハイコントラストの設定をオンにする / オフにする方法を教えてください。 から引用しました)

強制カラーモードの影響を受けるCSSプロパティ

forced-colors - 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' に強制されます

Chromeでの試し方

Macではシステム設定による強制カラーモードがないため[1] 、私はブラウザの開発モードによって強制カラーモードを試しています。Chromeでの試し方を紹介します。

  1. DevTools を開き、 ⌘ ⇧ P または3点リーダーから Run Command を選択します。
  2. コマンドパレットが開かれるため、 Emulate CSS forced-colors: active を選択し、強制カラーモードをエミュレートします。
  3. やめる場合はコマンドパレットの Do not emulate CSS forced-colors を選択すれば解除できます。

Chromeのコマンドパレットでforceと打ち込んだ時のキャプチャ

強制カラーモードを気にしないと何が起きる?

悪い点を具体的な名前をあげてしまうのはかなりやぶさかなのですが「こんなに大きなサービスでも気をつけないと問題が発生してしまうのか!」という驚愕によって気を引き締めるために愛するサービスをピックアップしてみました。もし何か問題があれば差し替えるので連絡ください。

Twitter(現X)のアイコンボタンが見えなくなる例

以下の画像はTwitterのサイドバーにある、投稿するアイコンボタンです。
ダークモードをユーザーエージェントで設定していて、強制カラーモードを選択すると以下のようにアイコンの色が背景と同化してしまい見えません。

ダークモードのtwitterの投稿ボタン
強制カラーモードの投稿ボタン、アイコンば背景色と同化していて見えない

これは、このボタンがプライマリーボタンになっていてページ内で目立つよう背景色とアイコン色が反転されていたため、強制カラーモードの上書きにより背景色がアイコン色と近づいた結果、起きています。

zenn のおしゃれなタブが、どれを選んでいるかわからなくなる例

これは、zenn 内のタブの例です。このタブは背景色のみで選択中のタブを表していたため、強制カラーモードにすると見えなくなってしまいました![2]


問題の対策方法!

対応策1: 実装方法を工夫する

borderがなくても見えないborderを設定する 🤔

おしゃれやモダンなサイトを強制カラーモードを見てみるとわかりますが、 focus時の背景色や box-shadow で差をつけたセクションの違いなどが全て平坦でわからなくなってしまいます。
そこで、普段から border-color などで透明な線や、背景色と同じ色のborderをつけることで、強制カラーモードでも見えるようになります。

ただ、これは設計段階から考えて入れないと難しそうですね。

フォームコントロール内部のSVGアイコンでは fill="currentColor" を用いる

Twitterの例のボタンでは、SVG要素のインラインスタイルでcolorが指定されていました。
このスタイルを外し、fill="currentColor による親要素のテキストカラーが当たるようにすることで上書き後のスタイルが当たり見えるようになりました。

DevToolでインラインスタイルを消した図
強制カラーモードでも見えるようになったTwitterアイコンボタン

これらの対応は全体設計せずとも少しずつ変更していくことができそうです。

対応策2: @media (forced-colors: active) でスタイルを調整する

forced-colors を使う方法です。最新ブラウザのみのサポートであれば、これで問題ありません。

以下のように、 box-shadow でスタイリングしている要素を強制カラーモード時には border に書き換えることで境界線が見えるようにできます。

.button {
  box-sizing: border-box;
  padding: 10px;
  border: none;
  box-shadow: -2px -2px 5px gray, 2px 2px 5px gray;
}

@media (forced-colors: active) {
  .button {
    /* 強制カラーモードでは box-shadow が 'none' に強制されるため、代わりに border を使用します。 */
    border: 2px ButtonText solid;
  }
}

強制カラーモード中にしている ButtonText という色はシステムカラーといい、以下のドキュメントで知ることができます。
6.2. System Colors - CSS Color Module Level 4

ちなみに以下にあるとおり、forced-colors を用いて過度に強制カラーモード向けの個別デザインを作成することは望ましくありません。あくまでも使いやすさの補足の調整のために細かく使うことが推奨されています。

まとめ

強制カラーモードというモードがあることと、対応方法を紹介しました。
対応例から見るとわかる通り、あまり複雑なことは必要ありません。そのため、もし余力があったら気にしてみてもいいかも?というかんじの宣伝になります!

一応、実際に使われているのか気になる人向けに以下の資料を添付しておきます。
第2回支援技術利用状況調査報告書 | 日本視覚障害者ICTネットワーク
が、アクセシビリティ対策というものはそれで困ってるユーザーの多さなどで比較されるものではなく、全く使えない人を1人でも取りこぼさないというのが理想だよねというのを心に刻んでほしいです。

参考資料

脚注
  1. Macでもシステム設定>アクセシビリティにコントラストをあげるという項目がありますが、このモードはディスプレイの描画方法を変更するのみで強制カラーモードのような色の上書きは発生しませんでした。 ↩︎

  2. とはいえ、この記事を書いている最中も強制カラーモードをしたままですがほぼ問題なく記事を書けましたし、検索もできました。タブには aria-current="page" もついていてしっかりしていますしとても良いサービスです! ↩︎

Discussion