【アクセシビリティ】アクセシビリティを意識したテーブルの作り方

## はじめに
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/8497bb58-1247-d419-e4f1-a1a1dc3d75ec.png)

みなさんアクセシビリティを意識して開発できていますか？

必要なところに`role属性`を記述したり、`tabキー`でフォーカスができるようにしたりなど、意識しないといけないことも多いです。
そのため、アクセシビリティを完璧にやろうとするのは一苦労です。

ただ、コンポーネントごとに区切って、アクセシビリティを理解しておけば、実装するタイミングに思い出しやすく、アクセシビリティも意識しやすいと思います。

そのため、この記事では「**テーブル**」に焦点を当てて、アクセシビリティを意識したテーブルの実装方法とテーブルで意識した方がいいアクセシビリティを解説しようと思います。

## アクセシビリティを意識したテーブルの仕様
### ⚪︎ テーブルとは？
テーブルは、`<table>` タグを使う静的な表形式の構造で、1つ以上の行と行それぞれに1つ以上のセルが含まれている要素です
テーブルは、インタラクティブな要素ではないため、セルはフォーカス可能な要素や選択可能な要素ではありません。
インタラクティブな要素を持つ表形式の場合は、グリッドパターンが使われます。

### ⚪︎ キーボードインタラクション
特になし

### ⚪︎ WAI-ARIA の役割、状態、プロパティ

+ テーブルのコンテナには `role="table"` を設定する
+ 行コンテナには、`role="row"` を設定し、`<table>` か、`role="rowgroup"` を持つ要素に所有される
+ 各セルは、行要素に所有され、以下の `role` のどれかが設定される
  + セルが列のタイトルか、ヘッダー情報を含む場合は、`role="columnheader"`
  + セルが行のタイトルか、ヘッダー情報を含む場合は、`role="rowheader"`
  + セルが列、行のヘッダー情報を含まない場合は、`role="cell"`
+ テーブルのラベルになる可視要素がある場合、テーブル要素にラベル要素のIDを `aria-labelledby` に設定する
  + そうでない場合は、テーブル要素に ラベルを指定した `aria-label` を設定する
+ テーブルにキャプションや説明がある場合、テーブル要素にキャプションや説明している要素のIDを `aria-describedby`に設定する
+ テーブルにソート可能な列や行が含まれる場合、ソートされた列や行のヘッダーセル要素に、`aria-sort` に適切な値を設定する
+ 一部の行や列が非表示の場合やDOMに存在しない場合がある場合、以下のプロパティを設定する
  + `aria-colcount` や `aria-rowcount` に、それぞれの列や行の総数を設定する
  + `aria-colindex` や `aria-rowindex` に、それぞれの行や列内のセルの位置を設定する
+ テーブルに複数の行や複数の列にまたがるセルが含まれている場合、`aria-rowspan` や `aria-colspan` を設定する

## アクセシビリティを意識したテーブルの完成形
<p class="codepen" data-height="400" data-default-tab="result" data-slug-hash="bGzKOeB" data-editable="true" data-user="sp_degu" style="height: 400px; 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/sp_degu/pen/bGzKOeB">
  Grid Accessibility</a> by でぐぅー | Qiita (<a href="https://codepen.io/sp_degu">@sp_degu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## アクセシビリティを意識したテーブルの作り方
### 1. HTMLを実装する
```sample.html
<table aria-label="商品の値段" cellspacing="0">
  <thead>
    <tr>
      <th>商品</th>
      <th>種類</th>
      <th>値段</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>りんご</td>
      <td>果物</td>
      <td>¥200</td>
    </tr>
    <tr>
      <td>いちご</td>
      <td>野菜</td>
      <td>¥400</td>
    </tr>
    <tr>
      <td>なし</td>
      <td>果物</td>
      <td>¥300</td>
    </tr>
    <tr>
      <td>スイカ</td>
      <td>野菜</td>
      <td>¥3000</td>
    </tr>
  </tbody>
</table>
```

### ２. CSSを実装する
```sample.css
body {
  background-color: #212529;
  color: #fff;
  display: grid;
  height: calc(100vh - 40px);
  margin: 0;
  padding: 20px 0;
  place-items: center;
  width: 100vw;
}

table {
  background-color: rgb(128 128 128 / .3);
  border-radius: 24px;
  padding: 16px;
  position: relative;
  width: 400px;
  background-blend-mode: luminosity;
  backdrop-filter: blur(50px);
  &::before {
    background: linear-gradient(135deg, rgb(255 255 255 / .4) 0, rgb(255 255 255 / 0) 40%, rgb(255 255 255 / 0) 60%, rgb(255 255 255 / .1) 100%);
    border: 1.4px solid transparent;
    border-radius: 24px;
    content: "";
    inset: 0;
    position: absolute;
    -webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0) border-box;
    -webkit-mask-composite: destination-out;
    mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0) border-box;
    mask-composite: exclude;
    z-index: -1;
  }
}

th {
  font-size: 16px;
  padding: 4px 8px;
  text-align: left;
  & + & {
    border-left: 1px solid rgb(255 255 255 / .2);
  }
}

td {
  border-top: 1px solid rgb(255 255 255 / .2);
  font-size: 16px;
  padding: 4px 8px;
  text-align: left;
  & + & {
    border-left: 1px solid rgb(255 255 255 / .2);
  }
}
```

## まとめ
この記事では、「**テーブル**」に焦点を当てて、アクセシビリティを意識したテーブルの実装方法とテーブルで意識した方がいいアクセシビリティを解説しました。

ぜひこの記事をストックして、テーブルを実装する時にアクセシビリティについて思い出してもらえると嬉しいです。

Advent Calendar 2023では、他のコンポーネントにも焦点を当てて、アクセシビリティについても解説しているので、ぜひ購読していてください。

https://qiita.com/advent-calendar/2023/degudegu2510

---

最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaに記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510