全フロントエンドエンジニアへ「画像表示には代替テキスト(alt属性)を適切につけよう」

# はじめに
こんばんは。立命館大学4回生で学生IT団体watnow所属の藤堂ゆうかです。
普段はWebフロントエンドエンジニアとして、趣味の開発をしています。UXやアクセシビリティが大好きです。

[watnow Advent Calendar 2024](https://qiita.com/advent-calendar/2024/watnow-calender)の15日目の担当として、代替テキストの重要性とその使い方を共有したいと思い、この記事を書きました。


Web・モバイルのフロントエンドを担うエンジニアにおける、
- **代替テキストを知らない人**
- **とりあえず全画像につけている人**
- **たまに意図的にプロパティをつけていない人**(私はこれでした)

に、適切な使い方を知ってもらいたいです。ぜひ最後まで読んで、明日から実践してみてください。


# 代替テキストとは
代替テキストとは、Webページにおける画像や動画の代わりとなるテキストのことです。画像が表示されないときや、スクリーンリーダー・音声読み上げソフトなどを使用するときに用いられます。


## 代替テキストを設定するメリット
代替テキストを設定することで、主に3つのメリットがあります。

### 1. さまざまな理由で画像が表示されないとき、代わりに画像を説明する
Webページでは時折、画像が表示されないことがあります。例えば、次のような場合です。

- 何かしらのエラーで画像が読み込めない場合
- ユーザーが画像の読み込みを無効にしている場合

こうしたケースでも、適切な代替テキストがあれば、画像の意図が正しく伝わります。

| 代替テキストなし | 代替テキストあり |
|:-:|:-:|
| ![代替テキストなしの場合の表示画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984887/44019422-12b8-140f-891a-41613dfa1776.png) | ![代替テキストありの場合の表示画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984887/7630401e-9f8f-7f66-29b5-54b50d2e96b2.png) |
| アイコン以外何も表示されていない | アイコンと共に画像の代替テキストが表示されている |

### 2. アクセシビリティの向上
代替テキストを設定することで、スクリーンリーダーやその他の支援技術で画像内容が視覚的に確認できないユーザーをサポートします。
これは三つのメリットの中でも特に重要であり、アクセシビリティ対応において欠かせない要素です。
これにより、画像が表示されない場合でも、その内容や意図を理解することが可能になります。

### 3. SEO効果が高まる
検索エンジンは画像を直接認識できません。代替テキストを介して画像の内容を理解し、SEOに役立てることができます。
参考ページ: [Google 画像検索 SEO ベスト プラクティス](https://developers.google.com/search/docs/appearance/google-images?hl=ja#discover-images)

# 代替テキストの設定の仕方

## Web(HTML)
画像埋め込み要素`<img>`に`alt属性`を指定することで設定することができます。

| alt属性 |コード|表示結果|
|:-:|:-:|:-:|
|あり| ```<img src="profile.png" alt="プロフィール画像" />```|![alt属性ありの場合の表示画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984887/7630401e-9f8f-7f66-29b5-54b50d2e96b2.png)
|なし| ```<img src="profile.png" />```  |![alt属性なしの場合の表示画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984887/44019422-12b8-140f-891a-41613dfa1776.png) 

:::note warn
alt属性説明の簡略化のために`src`と`alt`のみを指定していますが、他にも`loading`や`height`などの効果的なプロパティがあります。詳しくは、[mdn web docsにおけるimgタグの属性一覧](https://developer.mozilla.org/ja/docs/Web/HTML/Element/img#%E5%B1%9E%E6%80%A7)を参考にしてください。
:::

### alt属性を指定する上での注意点

#### 1. 明確で簡潔に画像の内容を説明する
alt属性に指定する内容は、画像と同じ意味が伝わるようなものが望ましいです。特に、下記のような書き方では適切に画像の意味を伝えることができません。

1. 画像そのもの存在を説明するもの
    - 例: `alt="画像"`
1. 画像のファイル名:
    - 例: `alt="profile.png"`

#### 2. 装飾画像には空文字列のalt属性を指定
代替テキストは、その画像を説明するための重要なテキストです。逆にいえば、**装飾のためだけに表示された画像には、代替テキストを指定しない方が良い**です。
ここで注意したいのが、**alt属性を完全に省略すると、画像ファイル名が読み上げられることがあります**。そのため、装飾画像の場合は、**alt属性に空文字列を指定**しましょう。


|  |コード|表示結果|
|:-:|:-:|:-:|
|装飾画像| ```<img src="decorative.png" alt="" />```|![alt属性が空文字指定の表示画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984887/56bff11a-24e9-a1f6-be25-32632dd7a110.png)|

:::note info
そのほかの注意点に関しては、[HTMLImageElement: alt プロパティ 使用上の注意](https://arc.net/l/quote/fabqgubn)を参考にしてください。
:::

## モバイル(Flutter,Swift)
モバイルにもWebページと同じように、画像表示における代替テキストが存在します。この記事では、FlutterとSwiftの2つを取り上げて紹介したいと思います。

:::note warn
Webを基準にして記述しているため、詳しい点については記事内で紹介した[alt属性を指定する上での注意点](#alt属性を指定する上での注意点)や公式サイトを参考にしてください。
:::

### Flutterにおける代替テキストの設定
- [Image class](https://api.flutter.dev/flutter/widgets/Image-class.html)
    - 代替テキストの設定には、[`semanticLabel`](https://api.flutter.dev/flutter/widgets/Image/semanticLabel.html)を使用
        - 例:
        - ```dart:dart
            Image.asset(
              'assets/profile.png',
              semanticLabel: 'プロフィール画像',
            )
            ```
    - 装飾画像の場合は、[`excludeFromSemantics`](https://api.flutter.dev/flutter/widgets/Image/excludeFromSemantics.html)をtrueに設定
        - 例:
        - ```dart:dart
            Image.asset(
              'assets/decorative.png',
              excludeFromSemantics: true,
            )
            ```

### Swiftにおける代替テキストの設定
- UIKitの[UIImageView](https://developer.apple.com/documentation/uikit/uiimageview)
    - 代替テキストの設定には、[`accessibilityLabel`](https://developer.apple.com/documentation/objectivec/nsobject/1615181-accessibilitylabel)を使用
        - 例:
        - ```swift:swift
            let imageView = UIImageView(image: UIImage(named: "profile.png"))
            imageView.accessibilityLabel = "プロフィール画像"
            ```
    - 装飾画像の場合は、[`isAccessibilityElement`](https://developer.apple.com/documentation/objectivec/nsobject/1615141-isaccessibilityelement)をfalseに設定
        - 例:
        - ```swift:swift
            let decorativeImageView = UIImageView(image: UIImage(named: "decorative.png"))
            decorativeImageView.isAccessibilityElement = false
            ```
- SwiftUIの[Image](https://developer.apple.com/documentation/swiftui/image)
    - 代替テキストの設定には、[`accessibilityLabel`](https://developer.apple.com/documentation/swiftui/view/accessibilitylabel(_:)-5f0zj)を使用
        - 例:
        - ```swift:swift
            Image("profile")
              .accessibilityLabel("プロフィール画像")

            ```
    - 装飾画像の場合は、[`accessibilityHidden`](https://developer.apple.com/documentation/swiftui/view/accessibilityhidden(_:))をtrueに設定
        - 例:
        - ```swift:swift
            Image("decorative")
              .accessibilityHidden(true)

            ```

# おわりに
ここまで読んでくださり、ありがとうございました。

この記事では代替テキストについて紹介してきましたが、これは、私が伝えたい**アクセシビリティのほんの一部**に過ぎません。もし興味があれば、去年アクセシビリティについて頑張ってまとめた記事があるので、ぜひ読んでみてください。

この記事をきっかけに、アクセシビリティ対応を意識してくれるエンジニアが少しでも増えたら嬉しいです。大変だよ！という方は、まずは代替テキストの設定から始めてみませんか？

:::note info
去年書いたアクセシビリティに関する記事
[今日から始めるアクセシビリティ~少しの気遣いでより使いやすいアプリへ~](https://qiita.com/yu-ka/items/b5d251cab7c7399acfba)
:::