アイコンボタンのアクセシブルな名前はボタンが持つべきかアイコンが持つべきか
SVGアイコンボタンのアクセシブルな名前の付け方について調査していた情報の整理と、個人的にまだ疑問の残るポイントを掘り下げていくスクラップ。
きっかけ
以下の記事へのコメントについて、社内で相談を受けて調査していた。
1つめに関しては、wozittoさんと認識はあっていると思うのですが、その上で、「SVGアイコンボタン」の例は誤りではないですが、ベストとも言えないのではないでしょうか?
SVGは画像なわけですから、以下のコードのように画像の代替テキストを提供するのがセマンティックスからは筋ではあるのかなと思うのです。
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>
-
button
要素にaria-label
を付与する -
svg
要素にrole="img"
を付与し、要素内にtitle
要素を入れる -
svg
要素にrole="img"
とaria-label
を付与する -
button
要素内にvisually-hidden
なクラスを持たせたspan
要素などでテキストを入れる
大前提
- 可視テキストを持たせられるのであればそれがベスト
- WAI-ARIAで補完するのではなくなるべくHTMLのセマンティクスを利用すべき(だが、今回出すパターンはどれもWAI-ARIAによる補完が行われる)
- 様々なブラウザとスクリーンリーダーの組み合わせで期待通りに読み上げられるべき(とはいえ、スクリーンリーダーについてはWindows PCを持っていないので今回はMac VoiceOverのみでの調査)
button
要素にaria-label
を付与する
1. きっかけとなった記事で紹介されていた方法。
<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などもこの方法だった
svg
要素にrole="img"
を付与し、要素内にtitle
要素を入れる
2. 記事中のコメントで提示されていた手法
<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による補完は行われている。
実際に、Google Chrome × Mac VoiceOverは問題なく読み上げられたが、Safari × Mac VoiceOverでは読み上げられなかった
Google Chrome × Mac VoiceOver
Safari × Mac VoiceOver
svg
要素にrole="img"
とaria-label
を付与する
3. 調査の結果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ではどちらも期待通りに読み上げられる
button
要素内にvisually-hidden
なクラスを持たせたspan
要素などでテキストを入れる
4. 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: none
やvisibility: 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で補完していることに変わりはない。 - 個人的な好みの問題として、ややハック気味なのであまり使いたくない。
ポイント:アイコンのみのボタンのアイコンは装飾なのか意味を持つ画像なのか
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 functionalityNOTE
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"には当てはまらないのではないか。であれば、アイコンが代替テキストを持つべきなのではないか。(記事のコメントの「画像の代替テキストを提供するのがセマンティックスからは筋ではある」という部分の解釈)
どちらかというとボタンの中の非テキストコンテンツは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.)
アイコンボタン内のアイコンを非テキストコンテンツと捉えていたが、アイコンボタンそのものが非テキストコンテンツとみなせるのかもしれない
記事にまとめたのでクローズ