【サラッと理解したい人向け】アクセシビリティの基礎を学ぶ

「アクセシビリティ」言葉は耳にするけど**体系的に学んだことがなかったのを恥ずかしく思えてきた**ので勉強します。

:::note info
【こんな方にオススメ！】
・アクセシビリティについて良く知らないけど、記事を読むのがつらい
・なんとなく知っているけど具体的に何すればいいのかわかっていない
:::

初学者向けのコンテンツです。
今コーディングを勉強されている方にはぜひ理解して活用していただきたいです！

## Accessibilityってなに？
どんな人にでも作ったサービスやウェブサイトを利用してもらえるように作ることだと解釈しています。
ちなみに、Accessibilityを調べる時は、「A11Y」という略語で表現されていることもあります。
AccessibilityのAからYまでの間に11文字が挟まれているためA11Yとなるそうです。

詳細は下記のサイドに記載があるので確認してください。

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

### なぜAccessibilityを大切にしないとダメなのか
コードの観点からすれば大きく2点あると考えています。

- 意味論的（セマンティック）HTMLはSEOの改善につながる
- ネットワーク速度が遅い人にとっても良い

:::note warn
携帯電話のユーザーや、ネットワーク速度が遅い人にとっての使いやすさを考慮するのもアクセシビリティだと認識できていませんでした。
:::

## HTMLのアクセシビリティとは？
HTMLのアクセシビリティはシンプルに「意味のないタグでマークアップするな」だと考えています。

誤ったHTMLのマークアップとは…
- クリックする要素に対しては`<div>`ではなく`<button>`を使う
- `<h1~h6>`を利用せず全てを`<p>`で全てマークアップする
- `<br>`を段落など体裁を整えるために利用する
- テーブルデザインにしたから`<table>`を利用する

などです。

### 良いセンマンティクスとは？
改めて学ぶと基本的なことですが、不足していたと感じたことがあったのでいくつか紹介します。

### リンクテキスト
テキストリンクは`<a>`で囲まれた範囲は意味の通るものでないといけません。
「ここをクリック」というテキストではなく、**リンク先がどのような内容のコンテンツがあるのか示唆できるのが望ましいとされています。**

知らない項目もありました。
- ダウンロードリンクは`download=""`を利用する
- `href`に`mailto:`を記述する際にCCや件名や本文も設定できる

などです。

#### 絶対パスと相対パスどっちがいいの？
絶対パスと相対パス、記述は2種類あるけどどっちがいいのかについては持論も述べておきます。

Googleは絶対パスを推奨しています。
> 可能な場合は、相対リンクではなく絶対リンクを使用します

https://support.google.com/webmasters/answer/35156?hl=ja

絶対パスの方がリンク切れが少ないからという理由で絶対パスが推奨されています。

:::note info
基本的にサイト内リンクである場合は相対パスで記述するのが良いと考えています。
:::

SEOの観点からすればどちらでも優位さはないとされているので、記述が短くて済む記法がいいのではないかと考えています。
リンクの数が多ければ**ファイル内の記述量も増え、ファイルの容量が大きくなります。**
ファイルサイズが小さい方が良いのは間違いないので削れるところは削っていくのがいいと考えています。


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

## CSS・JavaScriptのアクセシビリティとは？
CSSやJavaScriptの操作によって直接アクセシビリティを損なうものではないとされています。
しかし、スタイルや誤った動作の実装によってアクセシビリティを大きく損なうことになるので注意しましょう。

### CSSでアクセシビリティを損なうケース

CSSのスタイリングでアクセシビリティを損なうケースは`<h1~6>`に通常のテキストのようなスタイル、通常の`<p>`がboldにfont-sizeも大きいなどの本来の**HTMLタグの役割とは異なるスタイリングがされているような場合**が考えられます。

または、背景色と文字色が同系色で認識しにくい状態になることも考えられます。
背景色とのコントラストが十分かを確認するツールもあります！

https://webaim.org/resources/contrastchecker/

コントラストに問題なければ全ての項目に「Pass」と表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/a59ec20e-583d-51ae-2eee-2cab5ac83944.png" width="500">

コントラストが十分でなければ「Fail」と表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/e8721537-58dc-8556-980b-aa9a6d59a9c9.png" width="500">

### JavaScriptによってアクセシビリティを損なうケース
むやみにHTMLやCSSがJavaScriptによって生成することは推奨されていません。
JavaScriptの利用はFormのバリデートの提供などが該当します。

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

## WAI-ARIAとは？

W3Cによって定められた仕様で、要素に意味論を追加するHTML属性のことです。
WAI-ARIAにはロール（Role）、プロパティ（Property）、ステート（State）の3つがあります。

|属性|役割|
|--|--|
|Role|要素の役割を定義する|
|Property|要素の性質を定義し、追加の意図や意味論を与える|
|State|要素の現在の状態を定義する|

WAI-ARIAはウェブページの構造やDOMに影響を与えませんが、CSSの要素選択で利用できます。

:::note warn
WAI-ARIAの中にはブラウザーのサポートがされていない場合があるので注意が必要です。
:::

### WAI-ARIAの使うべきタイミング
有効なタイミングは4つとされています。
- 道しるべ/ランドマーク
- 動的なコンテンツの更新
- キーボードのアクセシビリティ向上
- 意味論的ではないコントロールのアクセシビリティ

### 道しるべ/ランドマークとは？
role属性を追加することで意味論的な価値を追加することです。

```diff_html
<header>
  <h1>title</h1>
-  <nav>
+  <nav　role="navigation">
    <ul>
      <li>list Item</li>
    </ul>
-    <form>
+    <form role="search">
      <input type="text">
    </form>
  </nav>
</header>
```
roleを付与してみます。
VoiceOverで確認するとnavはroleを付与する前からナビゲーションとして認識されます。
ただ、formの方は「検索form」として認識されます。

VoiceOverの起動の仕方は`Command`を押しながらTouchIDを素早く3回押すと起動し、無効にする時はもう一度同じ操作をします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/dfaeeec1-1105-6b30-04af-0cb1cb14c294.png)

:::note warn
TouchIDがないモデルの場合は「設定 > アクセシビリティ > VoiceOver」の項目を確かめてください。
:::

### 動的なコンテンツの更新
動的コンテンツとはページのリロードをすると更新が行われるコンテンツのことで**ライブリージョン（live region）**とも呼ばれます。

JavaScriptの`setINterval`などでページの更新が発生せずにコンテンツが更新された場合は読み上げソフトで検知できません。

それを通知するためのWAI-ARIAとして`aria-live`があります。

|属性値|通知タイミング|
|--|--|
|off|デフォルト値。更新が通知されない|
|polite|読み上げが終了したときなどに通知される|
|assertive|即座に通知される|

```html
<section aria-live="assertive">
```

`aria-atomic="true"`を設定することで変更されたコンテンツ全体を通知できます。
さらに`aria-relevant`を設定すればどんな変更のときに通知するかも設定可能です。
値は`additions`、`removals`、`text`、`all`の設定ができ、`additions`と`text`がデフォルトで設定されています。

### キーボードのアクセシビリティ向上
キーボードで操作可能な範囲を拡張することをいいます。
本来フォーカスできないコードをタブキーで移動できる対象にすることです。

`tabindex="0"`を利用するとタブキーによって付与した対象の要素にフォーカスが当たります。
JavaScriptによってフォーカスを受けられるようにする場合は`tabindex="-1"`を利用するようです。

### 意味論的ではないコントロールのアクセシビリティ
HTML構造が深くなった場合やCSSやJavaScriptによって複雑なUIを実現した場合に付与することが推奨されています。

具体的には下記のようなものが上げられます。

- formの中であればどのタブが選択されているか知らせる
- hiddenで隠してある要素を読み上げないようにする
- 複数ある関連要素のいくつ目なのか
- 要素がどの位置にある

設定することでよりよいアクセシビリティが実現できます。

https://developer.mozilla.org/ja/docs/Learn/Accessibility/WAI-ARIA_basics

## 【まとめ】アクセシビリティを学んでどのように活かすか？
アクセシビリティを改めて学んでみて、知らないことがまだまだ多いのが所感です。
今回勉強したことは表層的な部分に過ぎないと思います。
ただ、知っているのと知らないのとではコーディングの中でセマンティクスへの意識は高まると感じます。

SEOなどの業務に関わる方は学んでおいた方が良い領域だと感じました。