フロントエンドエンジニアのWeb開発アクセシビリティ入門②｜CSS/JavaScript

## 初めに
### 記事を書いた人について
2022年3月からフロントエンドエンジニアとして働き始めました。
2024年6月現在、約2年ほどフロントエンドエンジニアとしての実務経験を積んでいます。

### この記事について
上記の通り、約2年実務経験を積み、そろそろアクセシビリティについてしっかり学ばなければならないと感じました。
自分と同じようなフロントエンドエンジニアとしてアクセシビリティを学び始める方に向けて、自分が学んだことを以下の3つの記事に分けて公開します。
- [フロントエンドエンジニアのWeb開発アクセシビリティ入門①｜HTML](https://qiita.com/msuzuna/private/2b0114d4f76b62b95c7a)
- フロントエンドエンジニアのWeb開発アクセシビリティ入門②｜CSS/JavaScript（この記事）
- [フロントエンドエンジニアのWeb開発アクセシビリティ入門③｜WAI-ARIA](https://qiita.com/msuzuna/items/47d539c55d2b5757a302)

なお、この記事は主に以下のページを自分なりにわかりやすくした内容です。

https://developer.mozilla.org/ja/docs/Learn/Accessibility/CSS_and_JavaScript

## CSS
### 正しい意味付け
#### 標準的なテキスト
以下の点を考慮しましょう。
- 文章を読みやすくするために、フォントサイズや行の高さ、文字間隔などは分別のあるものを選ぶ
- 見出しと本文が区別できるようにする
- テキストの色と背景色のコントラストが十分である色の組み合わせを選ぶ

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="vYwZjJO" data-pen-title="標準的なテキスト" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/vYwZjJO">
  標準的なテキスト</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

:::note
[WCAG2.2 達成基準 1.4.12 テキストの間隔](https://waic.jp/translations/WCAG22/#text-spacing)にて以下の達成基準が記載されています。
- 行の間隔 (行送り) をフォントサイズの少なくとも 1.5 倍に設定する
- 段落に続く間隔をフォントサイズの少なくとも 2 倍に設定する
- 文字の間隔 (字送り) をフォントサイズの少なくとも 0.12 倍に設定する
- 単語の間隔をフォントサイズの少なくとも 0.16 倍に設定する
:::

#### 強調したテキスト
強調したテキストには`<em>`や`<strong>`タグを利用しましょう。
習慣的に、太字や斜体で書かれているテキストを強調と認識しやすいです。
```html
<em>なんと<em>無料で</em></em>利用できます。

<strong>ここからは有料です。</strong>
```

:::note
- `<em>`タグは入れ子にすることで強調の度合いを示すことができる
- `<strong>`タグは注意事項等、ユーザに必ず伝えたいテキストをマークアップするのに適している
:::

#### 略語
`<abbr>`タグを使うと良いでしょう。
略語に対するスタイル付けの慣習は、点線の下線で実装することです。
`title`属性に略していない言葉を設定することで、マウスをホバーさせると略していない言葉をツールチップとして表示できます。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="XWwNdyB" data-pen-title="&amp;lt;abbr&amp;gt;タグ" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/XWwNdyB">
  &lt;abbr&gt;タグ</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

#### リンク
リンクについてWeb開発者で自由にスタイリングできますが、標準的なスタイル付けに則る方がユーザにリンクであることを認識してもらいやすいです。
標準的なリンクの慣習は以下の通りです。
- 下線が引かれている
- 標準のテキストとは異なる色で表示されている（デフォルトは青）
- 訪問済みの場合はさらに別の色で表示されている（デフォルトは紫）
- アクティブになっている場合はさらに別の色で表示されている（デフォルトは赤）
- リンクにマウスオーバーすると、マウスポインターがポインターアイコンに変化する
- フォーカスが当たったり、アクティブ化されるとハイライトされる

#### フォーム要素
フォーム要素は[フロントエンドエンジニアのWeb開発アクセシビリティ入門①｜HTML UIコントロール](
https://qiita.com/msuzuna/private/2b0114d4f76b62b95c7a#ui%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%AB)の章で記述している通り、フォーカスが当たっていることがわかるスタイルがブラウザの既定で設定されています。
Web開発者は既定のスタイルを上書きできますが、期待されるような視覚的なフィードバックを大きく逸脱したり、完全に取り除いてしまったりすべきではありません。

#### テーブル
テーブルの見出しを目立つようにしたり、異なる行同士が見分けやすいようにシマウマ的な配色を使うと良いでしょう。
HTMLで留意すべき点は[フロントエンドエンジニアのWeb開発アクセシビリティ入門①｜HTML アクセシブルなデータ表](
https://qiita.com/msuzuna/items/2b0114d4f76b62b95c7a#%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B7%E3%83%96%E3%83%AB%E3%81%AA%E3%83%87%E3%83%BC%E3%82%BF%E8%A1%A8)に記述しています。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="GRaNBpZ" data-pen-title="CSS-テーブル" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/GRaNBpZ">
  CSS-テーブル</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### 色とそのコントラスト
テキストと背景色が十分に差があることを確認しましょう。
また、案内を色だけに頼らないようにしましょう。

:::note
[WCAG2.2 達成基準 1.4.3 コントラスト (最低限)](https://waic.jp/translations/WCAG22/#contrast-minimum)にて4.5:1 のコントラスト比を確保することが達成基準として記載されています。
:::

### ものごとを隠す
タブUIのように、すべてのコンテンツを一度に表示させないことが要求される場合があります。
以下の例では、`opacity: 0;`と`opacity: 1;`を切り替えることでタブを実現しています。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="NWVdNWQ" data-pen-title="タブUI" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/NWVdNWQ">
  タブUI</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

上記例のように、`opacity`でタブコンテンツを切り替える場合はスクリーンリーダーにはあまり影響がありません。
`visibility: hidden;`や`display: none;`はスクリーンリーダーがコンテンツを読み取れなくなってしまうので、しかるべき理由がない場合は使わないようにしましょう。
（上記のコードはあくまで例のために実装しており、タブの実装として最適なコードではありません。）

### ユーザがスタイルを上書きできることを受け入れる
視覚障害のあるユーザはすべての訪問先Webサイトでテキストを大きくしたいかもしれません。また、色覚障害のあるユーザはすべてのWebサイトを見やすい高コントラストの色に変更したいかもしれません。このようにユーザによってスタイルが変更された場合でも、うまく機能するように柔軟なものにしておくとよいでしょう。

:::note
[WCAG2.2 達成基準 1.4.8 視覚的提示](https://waic.jp/translations/WCAG22/#visual-presentation)において以下の内容が達成基準として記載されています。
- テキストは、支援技術なしで 200％までサイズ変更できる
- 利用者が、前景色と背景色を選択できる
:::

## JavaScript
複雑な機能をアクセシブルにするのは簡単ではありません。そのような場合でも、以下の点は配慮できると良いでしょう。
- マウスを使わないユーザが利用できるようにキーボードコントロールを実装する
- 色覚障害者が利用できるように、十分なコントラスがある色を使用する

### 過度のJavaScriptにともなう問題
JavaScriptによってHTML/CSSを生成するWebサイトはさまざまなアクセシビリティの問題や付随するその他の問題が発生します。そのため、JavaScriptによってHTML/CSSを生成するような実装は避けた方が良いでしょう。

### ひかえめに保つこと
Webページの基本的な機能はJavaScriptなしで動作するのが理想的です。以下のようにブラウザ内蔵の機能を使用するのが望ましいでしょう。
- クライアント側のフォーム検査を提供すること
- キーボードのみのユーザにとって操作可能な、HTMLの`<video>`用のカスタムコントロールを提供すること

フォームの実装は以下の点を考慮するとアクセシビリティを向上させることができます。
- クライアント側の検証によって、エラーをユーザに即時フィードバックする
- エラーが存在する時にだけエラーを表示させる

:::note
[WCAG2.2 達成基準 3.3.1 エラーの特定](https://waic.jp/translations/WCAG22/#error-identification)において「入力エラーが自動的に検出された場合は、エラーとなっている箇所が特定され、そのエラーが利用者にテキストで説明される。」ことが達成基準として記載されています。
:::

### JavaScriptのアクセシビリティのその他の問題
#### マウス特有のイベント
ユーザとの対話的動作のほとんどはイベントハンドラーを利用してクライアント側のJavaScriptで実装されます。
`mouseover`や`mouseout`、`dblclick`などのマウス特有のイベントはキーボードコントロールのようなマウス操作以外の仕組みを利用しているとアクセシブルではなくなってしまいます。

これらの問題を軽減するために、他の手段によってアクティブにできる類似イベントと二重化するのが良いでしょう。`focus`と`blur`はキーボードのユーザに対するアクセシビリティを提供してくれます。

## まとめ
この記事ではCSS、JavaScriptそれぞれに対してアクセシビリティ観点で考慮すべきことをまとめました。

フロントエンドエンジニアのWeb開発アクセシビリティ入門①｜HTMLは以下の記事にまとめています。

https://qiita.com/msuzuna/private/2b0114d4f76b62b95c7a

アクセシビリティ入門③｜WAI-ARIAは以下の記事にまとめています。

https://qiita.com/msuzuna/items/47d539c55d2b5757a302

## 参考サイト
本記事を執筆するに当たって勉強したものは以下の通りです。
- MDN-CSS と JavaScript のアクセシビリティのベストプラクティス：https://developer.mozilla.org/ja/docs/Learn/Accessibility/CSS_and_JavaScript
- WCAG2.2：https://waic.jp/translations/WCAG22/