# その機能がないと使えないアクセシビリティ設定

Source: https://easeweb.dev/learn/accessibility-settings
Topics: ページの構造 > アクセシビリティ設定を、その機能に頼らずに有効にできる (EN 301 549 5.2)
The fix: それぞれの設定を、その必要を持つ人が設定をオンにする前から届く場所、つまりヘッダーの先頭、それが変える内容より前に、サイトのハイコントラストモードと同じコントラストと大きさで置くか、加えて端末の対応する設定からも有効にします。端末の設定が届くのはそれをオンにした人だけなので、ほかの人も届く切り替えを並べて置く必要があります。
Test with: zoom, contrast measurement, reduced motion, keyboard
References: https://www.etsi.org/deliver/etsi_en/301500_301599/301549/03.02.01_60/en_301549v030201p.pdf https://www.w3.org/WAI/WCAG22/Understanding/contrast-enhanced.html https://www.w3.org/WAI/WCAG22/Understanding/pause-stop-hide.html https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-contrast https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-pressed https://www.w3.org/WAI/people-use-web/user-stories/

よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。

## 場面

サイトによっては、独自の設定を用意しています。ハイコントラストモード、大きな文字、アニメーションの一時停止、字幕、やさしい版などです。どれも、そのままではサイトを使えない人のためのものです。そのため、設定を有効にする切り替えを使うのはまさにその人たちで、しかも設定がまだオフの状態、つまり設定で変えたいはずの見た目や配置のままで使うことになります。設定が与えるものを必要とする切り替えは、その設定を必要とする人には使えません。

小さな公立図書館 Riverside Library は、落ち着いた今風のサイトに二つの設定を用意しています。グレーの文字が読みにくい人のための、黒地に白い文字と黄色のリンクのハイコントラストモードと、数秒ごとに切り替わる今週のイベントのバナーがあると読めない人のための、アニメーションを一時停止する切り替えです。

ハイコントラストの切り替えは、ヘッダーのメニューの後ろにあり、ヘッダーのほかの小さな文字と同じ、12ピクセルの #767676 のグレーで、枠線もありません。ロービジョンの利用者が、開館時間を確かめにサイトを開きます。大きな見出しは読めます。ところが、ヘッダーの端にある切り替え、つまりページのほかの部分を読めるようにしてくれる唯一のものは、薄いにじみにしか見えません。画面拡大ソフトでページの左上だけを表示していると、画面の外にあって目に入りもしません。

一時停止の切り替えは読みやすく、問題は別のところにあります。切り替えはフッターにあり、イベントのバナーとページ全体の後ろにあります。横で何かが動いていると文章を読めない人は、動きを止めるたった一つの切り替えに届くまでに、バナーを読み過ごすか、バナーのすべてのリンクをTabで通り過ぎなければなりません。

## 確認できる問題

まず、規格が求めていないことです。EN 301 549 は、ハイコントラストモード、文字サイズの切り替え、一時停止の切り替えなど、どんな設定もWebサイトに用意することを求めていません。サイトのデザイン自体は、設定があってもなくても、EN 301 549 の9章を通じてWCAG 2.1のレベルAとAAを満たす必要があります。つまり、標準の見た目のままで十分なコントラストがあり、拡大しても崩れないことが前提です。設定はその上に加えるものです。

規格が求めるのは5.2です。製品に説明されたアクセシビリティ機能がある場合、必要に応じた機能を「その必要を満たさない方法に頼らずに」有効にできることです。確かめ方は、どの設定でも同じです。その設定が何を与えるのかを考え、切り替えがそれを必要としていないかを確かめます。字幕の切り替えは聴力を、スクリーンリーダー向けのモードは視力を、キーボード操作のモードはマウスを必要としてはいけません。図書館の二つの切り替えは、二通りの形でこの確かめに失敗します。ハイコントラストモードは標準の見た目を読めない人のためのものなのに、その切り替えは標準の見た目でいちばん薄い文字で描かれています。一時停止は動きに耐えられない人のためのものなのに、その切り替えには動きを通り過ぎてからしか届きません。

この条項は、説明されたアクセシビリティ機能を持つWebコンテンツに適用されます。サイトがアクセシビリティ方針やヘルプのページで設定を説明していれば、それに当たります。EN 301 549 の12.1.1が、その情報を載せる場所として挙げているページです。WCAGにはない要件なので、WCAGの達成基準をすべて満たしたサイトでも、この点では不合格になり得ます。たとえばフッターの切り替えは、WCAG 2.2.2が求める、バナーを一時停止する方法そのものです。2.2.2の解説書は、その方法をどこに置くべきかについて何も述べていません。

## 利用者への影響

この問題は、設定が想定するすべての人に及びます。どの人にも、その人のための設定があるため、同じ誤りは誰でも締め出し得ます。図書館の二つの切り替えで締め出されるのは、ロービジョンの人と、注意の困難を持つ人の多くを含む、動きのせいで読めなくなる人です。ほかの設定を同じように置くとほかの人がどう締め出されるかは、注記のとおりです。前庭障害のある人は、動きでめまいや吐き気を起こすことがあります。その人にとって、動きの後ろにある切り替えに届くということは、避けたいものを見続けることを意味します。

## 自動チェックとAIの限界

チェックツールは、設定の切り替えをページ自体の基準で測り、その設定が何のためのものかでは測りません。ハイコントラストの切り替えのグレーは白に対して4.54:1で、WCAG 1.4.3が文字に求める4.5:1を満たすため、axe もほかのコントラストのチェックも、AAの基準では合格にします。一時停止の切り替えは名前があり、読みやすく、Tabで届くため、これも合格です。これらのボタンが設定への入り口であることは、どのチェックにも分かりません。この診断では、「ハイコントラスト」「アニメーションを停止」「文字サイズ」「High contrast」など、アクセシビリティの設定の名前を持つ操作要素がページにあると、その必要を念頭に人が確認できるよう、確認の手がかりとして報告します。その必要を持つ人が実際に届くかどうかは判断できません。

AIツールに「ハイコントラストの切り替えを追加して」「アニメーションを止める方法を追加して」と頼むと、多くのサイトと同じように、周りのリンクと同じ見た目でヘッダーに置いたり、ほかのリンクと一緒にフッターに置いたりすることがあります。その切り替えが誰のためのものかを尋ねる手段がありません。

## 修正前：設定で置き換えるはずの見た目で描いた切り替え

```html
<header>
  <a href="/" class="logo">Riverside Library</a>
  <nav>…</nav>
  <div class="tools">
    <button type="button" id="contrast" aria-pressed="false">ハイコントラスト</button>
  </div>
</header>
```

```css
.tools button {
  font-size: 12px;
  color: #767676;
  background: none;
  border: 0;
}
.high-contrast body { background: #000; color: #fff; }
.high-contrast a, .high-contrast .tools button { color: #ff0; }
```

```js
const contrast = document.getElementById('contrast');
contrast.addEventListener('click', () => {
  const on = contrast.getAttribute('aria-pressed') !== 'true';
  contrast.setAttribute('aria-pressed', on);
  document.documentElement.classList.toggle('high-contrast', on);
});
```

ハイコントラストの切り替えはヘッダーでいちばん薄く小さい文字で、しかも最後にあります。見つけるには、このモードが補うはずの視力が必要です。

## 修正前：止めたいものの後ろに置いた切り替え

```html
<header>
  <a href="/" class="logo">Riverside Library</a>
  <nav>…</nav>
</header>
<main>
  <div class="events">…</div>
  …
</main>
<footer>
  …
  <button type="button" id="motion" aria-pressed="false">アニメーションを停止</button>
</footer>
```

```css
.events .slide { animation: rotate 12s infinite; }
.still .events .slide { animation: none; }
```

```js
const motion = document.getElementById('motion');
motion.addEventListener('click', () => {
  const on = motion.getAttribute('aria-pressed') !== 'true';
  motion.setAttribute('aria-pressed', on);
  document.documentElement.classList.toggle('still', on);
});
```

一時停止の切り替えははっきり読めますが、画面の上でもTabの順序でも、バナーとページ全体の後ろにあります。届くには、止めたい動きを通り過ぎなければなりません。

## 修正後：設定を先頭に、オンにする前から使える形で置く

```html
<header>
  <div class="tools">
    <button type="button" id="contrast" aria-pressed="false">ハイコントラスト</button>
    <button type="button" id="motion" aria-pressed="false">アニメーションを停止</button>
  </div>
  <a href="/" class="logo">Riverside Library</a>
  <nav>…</nav>
</header>
<main>
  <div class="events">…</div>
  …
</main>
```

```css
.tools button {
  font-size: 18px;
  font-weight: 700;
  color: #000;
  background: #fff;
  border: 2px solid #000;
  border-radius: 6px;
  padding: 6px 14px;
}
.high-contrast body { background: #000; color: #fff; }
.high-contrast a, .high-contrast .tools button { color: #ff0; }
.high-contrast .tools button { background: #000; border-color: #ff0; }
.events .slide { animation: rotate 12s infinite; }
.still .events .slide { animation: none; }
```

```js
for (const [id, mode] of [['contrast', 'high-contrast'], ['motion', 'still']]) {
  const button = document.getElementById(id);
  button.addEventListener('click', () => {
    const on = button.getAttribute('aria-pressed') !== 'true';
    button.setAttribute('aria-pressed', on);
    document.documentElement.classList.toggle(mode, on);
  });
}
```

どちらの切り替えも、設定を必要とする人が、設定をオンにする前から使えるようになります。二つとも、ヘッダーの先頭、つまり画面拡大ソフトが最初に映す場所であり、Tabで最初に届く場所に、バナーより前に置きます。動きを見続ける前に止められます。見た目は、ハイコントラストモードが文字を描くのと同じです。18ピクセルの太字で、黒い枠線の中に白地に黒の21:1、モードをオンにすると黒地に黄色です。

## 修正後：加えて端末の設定に従う

```html
<header>
  <a href="/" class="logo">Riverside Library</a>
  <nav>…</nav>
  <div class="tools">
    <button type="button" id="contrast" aria-pressed="false">ハイコントラスト</button>
  </div>
</header>
<main>
  <div class="events">…</div>
  …
</main>
<footer>
  …
  <button type="button" id="motion" aria-pressed="false">アニメーションを停止</button>
</footer>
```

```css
.tools button {
  font-size: 12px;
  color: #767676;
  background: none;
  border: 0;
}
.high-contrast body { background: #000; color: #fff; }
.high-contrast a, .high-contrast .tools button { color: #ff0; }
.events .slide { animation: rotate 12s infinite; }
.still .events .slide { animation: none; }
```

```js
for (const [id, mode, query] of [
  ['contrast', 'high-contrast', '(prefers-contrast: more)'],
  ['motion', 'still', '(prefers-reduced-motion: reduce)']
]) {
  const button = document.getElementById(id);
  const asked = matchMedia(query);
  const set = (on) => {
    button.setAttribute('aria-pressed', on);
    document.documentElement.classList.toggle(mode, on);
  };
  set(asked.matches);
  asked.addEventListener('change', (event) => set(event.matches));
  button.addEventListener('click', () => set(button.getAttribute('aria-pressed') !== 'true'));
}
```

端末でコントラストを上げる設定や視差効果を減らす設定をオンにしている人には、ページを開いた時点で、ハイコントラストの見た目や止まったバナーが表示され、何も探す必要がありません。切り替えはオンの状態で示され、オフにもできます。ただし届くのは、その設定をオンにした人だけです。それ以外の人は、設定を変えられない図書館のパソコンを使う人も含めて、薄い切り替えを探し、バナーを通り過ぎて一時停止までたどり着かなければなりません。そのため、一つ目の修正と並べる必要があります。

## どの方法を選ぶか

一つ目を使ってください。ハイコントラストモードと同じコントラストと大きさで、ヘッダーの先頭、バナーより前に置いた切り替えは、端末の設定に関係なく、サイトを訪れるすべての人に届きます。二つ目は一つ目に加える価値があります。必要なことをすでに端末に伝えている人が、サイトごとに伝え直さずに済むからです。ただし、それだけでは設定をしていない人が取り残されるため、十分ではありません。

## 実装の判断

サイトが用意するどの設定にも、同じ原則が当てはまります。有効にする方法が、その設定で補うものに頼ってはいけません。ほかのよくある例を挙げます。

- 小さな文字で書いた文字サイズの切り替えは、図書館のハイコントラストの切り替えと同じ誤りです。少なくとも本文の大きさで描き、ブラウザーの文字サイズの設定も効くように、サイトの文字を rem で指定します。ボックスは、[拡大した文字が切れる、高さ固定のボックス](/ja/learn/resize-text)のとおり、文字とともに広がるようにします。
- 「字幕」や「手話」の選択肢を動画の語りでしか説明しないと、それを必要とする人に届きません。見えるラベルを付けたボタンとして、プレーヤーのバーに置きます。
- やさしい版や「読み上げ」のボタンを長い段落の中でしか案内しないと、必要とする読み手が見落とします。短く平易な名前とアイコンを付けて、ページの先頭に置きます。

操作要素は、色のほかは設定がオンでもオフでも同じ見た目にして、設定をオフにしたいときにもう一度見つけられるようにします。状態は aria-pressed で示し、名前は変えません。「ハイコントラスト」が押されているか、押されていないかで示し、「標準のコントラスト」のように変わる名前にはしません。選んだ内容は Cookie やローカルストレージに保存し、次のページでも保たれるようにします。

バナーは、切り替えを使わなくても、端末で動きを減らすよう求めている人には止まって表示されるべきです。[動きを減らす設定を無視するアニメーション](/ja/learn/reduced-motion)で説明しています。また、一つのバナーしか止めない一時停止では、ページのほかの場所の動きには役に立ちません。切り替えで、サイトが動かすすべてのアニメーションを止めるようにします。

Windows のコントラスト テーマは仕組みが違います。サイト独自のモードがどうであっても、強制配色で、サイトの色を利用者自身の色に置き換えます。サイトはそれに備える必要があり、その方法は[ハイコントラストモードで消えるフォーカス・アイコン・選択状態](/ja/learn/forced-colors)で説明しています。サイト独自のハイコントラストモードはそれ以外の人のためのもので、だからこそ、その切り替えは見つけやすくなければなりません。

独自の設定パネルを持つ、画面に浮かぶアクセシビリティのオーバーレイは、この問題を解決しません。むしろ同じ誤りを繰り返すことがあります。起動ボタンは小さなアイコンで、パネルの切り替えも小さな文字です。最も大切なコントラスト、文字サイズ、動きの設定は、試験できるよう、サイト自体のデザインに組み込むほうが確実です。

## 修正の確認

1. サイトにあるそれぞれの設定について、何のための設定かを挙げる。そのうえで、設定をオフにしたまま、その必要を持つ人と同じ方法で、トップページの上から切り替えを見つけて操作する。コントラストや文字サイズは400%の拡大表示か画面拡大ソフトで、動くものはページを見ずにTabで、字幕は音を消して確かめる。どの切り替えも、メインのメニューより前、それが変える内容より前にあることを確認する。
2. コントラストや文字サイズなど、見た目の設定の操作要素の文字を測る。標準の見た目でもハイコントラストの見た目でも、16ピクセル以上、背景とのコントラスト比が7:1以上で、枠線か塗りが3:1以上あることを確認する。
3. 端末のコントラストを上げる設定（macOSまたはiOS）と視差効果を減らす設定をオンにしてサイトを開く。ハイコントラストの見た目で、バナーが止まった状態で開き、それぞれの操作要素が押された状態で示され、設定をオフにもできることを確認する。
4. それぞれの設定を、その切り替えからもう一度オフにし、設定がオンの間も切り替えが同じように見つけやすく、操作しやすいことを確認する。

OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。ヘッダー、設定、アニメーションのデザインを変えたときに、再度確認します。

## 制限

このガイドは、サイト独自のアクセシビリティ設定と、それを有効にする方法を扱います。サイトの標準の見た目のコントラスト（WCAG 1.4.3。[ブランドカラーや写真の上でコントラストが足りない文字](/ja/learn/text-contrast)で扱います）、WCAG 2.2.2が求める一時停止（[一時停止できない、流れる文字、カルーセル、アニメーション](/ja/learn/moving-content)で扱います）、ハイコントラストモード自体でフォーカス、アイコン、選択状態をどう見えるように保つかは扱いません。EN 301 549 の5.2は製品が説明している機能だけに適用されるため、設定のないサイトはこの点で不合格になりません。ただし、一部の読み手が頼っている設定をやめる理由にはなりません。それぞれの設定が想定する人に、その人自身の端末と設定で試してもらってください。

---

このガイドをコーディングエージェントで使う: MCP https://easeweb.dev/mcp（設定は https://easeweb.dev/ja/services/developers）
