今からでもできそうなアクセシビリティコーディング

## 背景

アクセシビリティコーディングについて勉強中です。
とりあえずすぐに取り組めそうなものを抜粋しています。

他にもできることはたくさんあると思いますが、
こういうのもあるんだ程度に思っていただけると幸いです！

また、間違えている点があればご指摘お願いします！

## 代替テキスト/読み上げ

### 装飾的な画像のalt属性

- 装飾的画像や、文中の情報と重複する画像では `alt=""` にする。
  - 例: 設定アイコンに `alt="設定"` を入れると「設定、設定」と読み上げられるため、 `alt=""` にする。
  - `alt` 属性がないと画像のファイル名が読み上げられたりするため、必ず `alt` を指定する。

### CSSの`background`で意味のある画像を表示しない

- `background-image` で表示するとスクリーンリーダーが読み上げないため、`img` 要素を使用する。

### SVG画像の代替テキスト

- インラインSVGを使用する際は `role="img"` と `aria-label="代替テキスト"` を付与。
  ```html
  <svg role="img" aria-label="代替テキスト">...</svg>
  ```
  - 他にも `title` 要素や `aria-labelledby` で対応可能。

### テーブルのラベル付け

- `caption` 要素を使うことで、表の内容を明示できる。
- `caption` に対応する要素がある場合は `aria-labelledby` で紐付ける。
- `caption` を使えない場合は `aria-label` を使用。
  ```html
  <!-- captionの場合 -->
  <table>
  <caption>売り上げデータ</caption>
  ・・・
  </table>

  <!-- aria-labelledbyの場合 -->
  <h2 id="heading">売り上げデータ</h2>
  <table aria-labelledby="heading">
  ・・・
  </table>

  <!-- aria-labelの場合 -->
  <table aria-label="売上データ">
  ・・・
  </table>
  ```

### アクセシブルな名前の付与

- インタラクティブ要素に適切な名前を付ける。
  ```html
  <!-- 悪い例（「ボタン」とだけ読み上げられる） -->
  <button><img src="search-icon.png" alt=""></button>

  <!-- 良い例（「ボタン、検索」と読み上げられる） -->
  <button><img src="search-icon.png" alt="検索"></button>
  <button><img src="search-icon.png" alt="">検索</button>
  ```
- 入力フィールドに適切なラベルを付ける。
  ```html
  <!-- 可視ラベルがある場合 -->
  <label for="username">名前</label>
  <input type="text" id="username">

  <!-- 可視ラベルがない場合 -->
  <input type="text" aria-label="名前">
  ```

## ランドマーク

適切にランドマークを設定することで、スクリーンリーダー利用者はページ全体の構造を素早く把握し、目的のコンテンツにスムーズに移動できるようになります。

例えば、`<main>` 要素を適切に指定することで、スクリーンリーダーは「主要なコンテンツはここにある」と認識します。同様に、`<nav>` を使用すれば「ここはナビゲーションメニュー」と判断できます。

### ランドマークの種類

ページの構造を明確にするため、HTMLのランドマーク要素を使用する。

| ロール             | 要素                       | 役割              |
| --------------- | ------------------------ | --------------- |
| `main`          | `<main>`                 | 主要なコンテンツ        |
| `nav`           | `<nav>`                  | ナビゲーション         |
| `search`        | `<search>`               | 検索機能            |
| `banner`        | `<header>`（特定の条件下で）      | ヘッダー            |
| `contentinfo`   | `<footer>`（特定の条件下で）      | フッター            |
| `complementary` | `<aside>`                | 補助セクション（サイドバー等） |
| `form`          | `<form>`                 | フォーム            |
| `region`        | `<section>`（アクセシブルネーム必須） | 重要な領域           |


## フォーカス

### クリックさせたくないボタンには `disabled` をつける

- キーボード操作でも無効なことが明示される。

### `div` や `span` にクリックイベントをつける場合

- `tabindex="0"` でフォーカス可能にし、 `role="button"` を指定。
  ```html
  <div tabindex="0" role="button" onclick="handleClick()" onkeydown="handleKeyDown(event)">カスタムボタン</div>
  <script>
    function handleClick() { alert('クリックされました！'); }
    function handleKeyDown(event) {
      if (event.key === "Enter" || event.key === " ") {
        event.preventDefault();
        handleClick();
      }
    }
  </script>
  ```

### フォーカスのアウトラインを見えるようにする

- `:focus-visible` を活用し、キーボード操作時のみアウトラインを表示。
  ```css
  button:focus-visible {
    outline: 2px solid blue;
  }
  ```

## ユーザビリティ

### `maximum-scale=1.0`、`user-scalable=no` を指定しない

- これらを指定するとユーザーが拡大できなくなり、視認性が下がる。

```html
<meta name="viewport" content="width=device-width, initial-scale=1">
```

---

アクセシビリティは小さな工夫の積み重ねなので、このような小さな取り組みから頑張っていきましょう！