Closed13

アイコンボタンのアクセシブルな名前はボタンが持つべきかアイコンが持つべきか

Taiga KiyokawaTaiga Kiyokawa

SVGアイコンボタンのアクセシブルな名前の付け方について調査していた情報の整理と、個人的にまだ疑問の残るポイントを掘り下げていくスクラップ。

きっかけ

以下の記事へのコメントについて、社内で相談を受けて調査していた。

1つめに関しては、wozittoさんと認識はあっていると思うのですが、その上で、「SVGアイコンボタン」の例は誤りではないですが、ベストとも言えないのではないでしょうか?
SVGは画像なわけですから、以下のコードのように画像の代替テキストを提供するのがセマンティックスからは筋ではあるのかなと思うのです。

https://zenn.dev/moneyforward/articles/b5c9b060cf9237

Taiga KiyokawaTaiga Kiyokawa

SVGアイコンボタンにアクセシブルな名前を持たせる方法

以下のようにsvg要素のみを持つbutton要素にアクセシブルな名前(accessible name)を持たせる方法は主に以下の4パターンあると考える。

<button>
  <svg width="24" height="24" viewBox="0 0 24 24">
    <path d="M0 0h24v24H0z" fill="none"/>
    <path d="M6 6l12 12M6 18L18 6" stroke="#000" stroke-width="2"/>
  </svg>
</button>
  1. button要素にaria-labelを付与する
  2. svg要素にrole="img"を付与し、要素内にtitle要素を入れる
  3. svg要素にrole="img"aria-labelを付与する
  4. button要素内にvisually-hiddenなクラスを持たせたspan要素などでテキストを入れる
Taiga KiyokawaTaiga Kiyokawa

大前提

  • 可視テキストを持たせられるのであればそれがベスト
  • WAI-ARIAで補完するのではなくなるべくHTMLのセマンティクスを利用すべき(だが、今回出すパターンはどれもWAI-ARIAによる補完が行われる)
  • 様々なブラウザとスクリーンリーダーの組み合わせで期待通りに読み上げられるべき(とはいえ、スクリーンリーダーについてはWindows PCを持っていないので今回はMac VoiceOverのみでの調査)
Taiga KiyokawaTaiga Kiyokawa

1. button要素にaria-labelを付与する

きっかけとなった記事で紹介されていた方法。

<button aria-label="閉じる">
  <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">
    <path d="M0 0h24v24H0z" fill="none"/>
    <path d="M6 6l12 12M6 18L18 6" stroke="#000" stroke-width="2"/>
  </svg>
</button>
  • svg要素のアイコンは単なる装飾という意図
  • Zennはじめ、Slackなどもこの方法だった

ZennのハートマークのみのSVGアイコンボタンをdevToolsで検証して、button要素にaria-label="いいね"が付与されている

Taiga KiyokawaTaiga Kiyokawa

2. svg要素にrole="img"を付与し、要素内にtitle要素を入れる

記事中のコメントで提示されていた手法

<button>
  <svg role="img" width="24" height="24" viewBox="0 0 24 24">
    <title>閉じる</title>
    <path d="M0 0h24v24H0z" fill="none"/>
    <path d="M6 6l12 12M6 18L18 6" stroke="#000" stroke-width="2"/>
  </svg>
</button>
  • svg要素は装飾ではなく意味を持つ画像であり、代替テキストを持つべきという意図
  • インタラクティブな要素内のsvg要素のtitle要素はブラウザとスクリーンリーダーの組み合わせによっては読み上げられないことがある
  • aria-labelを避けることができる方法だが、svg要素にrole='img'を与えているためWAI-ARIAによる補完は行われている。

https://www.scottohara.me/blog/2019/05/22/contextual-images-svgs-and-a11y.html#:~:text=SVGs within links and buttons

実際に、Google Chrome × Mac VoiceOverは問題なく読み上げられたが、Safari × Mac VoiceOverでは読み上げられなかった

Google Chrome × Mac VoiceOver

Google Chromeで開いているcodepenのデモをMacのVoiceOverで読み上げて、「閉じる, button, group」と出力されている

Safari × Mac VoiceOver

Safariで開いているcodepenのデモをMacのVoiceOverで読み上げて、「button」とだけ出力されている

Taiga KiyokawaTaiga Kiyokawa

3. svg要素にrole="img"aria-labelを付与する

調査の結果1番良さそうだと思った方法。実際きっかけとなった記事のコメントへの返信もそのように結論づけている。

<button>
  <svg role="img" aria-label="閉じる" width="24" height="24" viewBox="0 0 24 24">
    <path d="M0 0h24v24H0z" fill="none"/>
    <path d="M6 6l12 12M6 18L18 6" stroke="#000" stroke-width="2"/>
  </svg>
</button>
  • svg要素は装飾ではなく意味を持つ画像であるという意図は2と同じ
  • これなら少なくともGoogle Chrome × Mac VoiceOverとSafari × Mac VoiceOverではどちらも期待通りに読み上げられる
Taiga KiyokawaTaiga Kiyokawa

4. button要素内にvisually-hiddenなクラスを持たせたspan要素などでテキストを入れる

1.1.1 画像に代替テキストを提供する - Ameba Accessibility Guidelinesなどで推奨されている方法。
以下の例ではScreen Readers - Tailwind CSS.sr-onlyクラスのpropertiesを使用している。

<button>
  <span class="visually-hidden">閉じる</span>
  <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">
    <path d="M0 0h24v24H0z" fill="none"/>
    <path d="M6 6l12 12M6 18L18 6" stroke="#000" stroke-width="2"/>
  </svg>
</button>

<style>
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}
<style>
  • display: nonevisibility: hiddenはAccessibility Object Modelからも無視されてしまうのでそれらを使わずに視覚的に隠す方法がいわゆるVisually Hidden
  • svg要素に使うよりかはAmebaの例のようにクラスだけ指定されている空のspan要素や、Font Awesomeアイコンなどを表示するためのi要素などに有用な印象
  • 『Webアプリケーションアクセシビリティ―今日から始める現場からの改善』の「第2章 Webアクセシビリティの基礎」の「2.3 非テキストコンテンツのマシンリーダビリティ」によると、「Visually Hiddenはブラウザによっては、widthやheightの値によっては要素を無視することがある」と記述されている
  • この方法も1と同様に非テキストコンテンツ(今回の場合はsvg要素)を装飾とみなしている
  • 2と同様にaria-labelを避ける方法だが、装飾とみなしたアイコンにaria-hiddenを使用しているため、WAI-ARIAで補完していることに変わりはない。
  • 個人的な好みの問題として、ややハック気味なのであまり使いたくない。
Taiga KiyokawaTaiga Kiyokawa

ポイント:アイコンのみのボタンのアイコンは装飾なのか意味を持つ画像なのか

WCAG 2.2 Success Criterion 1.1.1 Non-text Contentの例外に相当するか否か。

Decoration, Formatting, Invisible
If non-text content is pure decoration, is used only for visual formatting, or is not presented to users, then it is implemented in a way that it can be ignored by assistive technology.

pure decoration
serving only an aesthetic purpose, providing no information, and having no functionality

NOTE
Text is only purely decorative if the words can be rearranged or substituted without changing their purpose.

EXAMPLE
The cover page of a dictionary has random words in very light text in the background.

ボタンが持つアイコンはそれ自体が情報や機能をユーザーに伝えているため、"providing no information, and having no functionality"には当てはまらないのではないか。であれば、アイコンが代替テキストを持つべきなのではないか。(記事のコメントの「画像の代替テキストを提供するのがセマンティックスからは筋ではある」という部分の解釈)

Taiga KiyokawaTaiga Kiyokawa

どちらかというとボタンの中の非テキストコンテンツは1.1.1の例外のうちControls, Inputに該当するのかも

Controls, Input
If non-text content is a control or accepts user input, then it has a name that describes its purpose. (Refer to Success Criterion 4.1.2 for additional requirements for controls and content that accepts user input.)

Taiga KiyokawaTaiga Kiyokawa

アイコンボタン内のアイコンを非テキストコンテンツと捉えていたが、アイコンボタンそのものが非テキストコンテンツとみなせるのかもしれない

このスクラップは2023/11/20にクローズされました