インラインSVGの代替テキストはどうするべきか

広告
最近アイコンボタンのアクセシブルな名前はボタンが持つべきかアイコンが持つべきかという記事を読んで、SVGの代替テキストについて改めて考えさせられたので自分なりの考えをまとめました。
一番確実な方法はimg
要素で読み込んでalt
属性を付与することだと思いますが、CSSで装飾を変えられるインラインSVGの利点を捨てるのも難しいのでインラインSVGにどうやって代替テキストを含めるか?のみに焦点を当てていきます。
自分の中での結論
先に結論から伝えますと、理想を言えば 「svg
の中にtitle
要素を含み、role="img"
とtitle
と紐づけたaria-labelledby
で実装する」 のがベストだと思います。ただし、この方法では不都合な点がいくつか孕んでいるので現実は冒頭で紹介した記事の2.で触れられているような 「Visually Hiddenなテキストをsvg
に隣接し、svg
はaria-hidden="true"
する」 になってしまいます。
当ブログの汎用アイコンは現実の方で実装していますが、フッターのブランドリンクについては理想の方でマークアップを行っています。
理想
<svg role="img" aria-labelledby="{uuid}" viewBox="0 0 24 24" height="16" width="16"> <title id="{uuid}">新しいウィンドウが開きます</title> <path d="M17 2H22V7" /> <path d="M21 13V19C21 20.1046 20.1046 21 19 21H5C3.89543 21 3 20.1046 3 19V5C3 3.89543 3.89543 3 5 3H11" /> <path d="M13 11L21.5 2.5" /></svg>
svg
にtitle
要素を含み、そこで代替テキストを指定- 「画像」と読み上げてもらうために
role="img"
を指定 svg
の代替テキストを読み上げてもらうためにtitle
とsvg
をaria-labelledby
で紐づける
現実
<svg aria-hidden="true" viewBox="0 0 24 24" height="16" width="16"> <path d="M17 2H22V7" /> <path d="M21 13V19C21 20.1046 20.1046 21 19 21H5C3.89543 21 3 20.1046 3 19V5C3 3.89543 3.89543 3 5 3H11" /> <path d="M13 11L21.5 2.5" /></svg><span class="visually-hidden">新しいウィンドウが開きます</span>
.visually-hidden { position: fixed !important; inset: 0 !important; display: block !important; inline-size: 4px !important; block-size: 4px !important; padding: 0 !important; margin: 0 !important; contain: strict !important; pointer-events: none !important; visibility: visible !important; border: none !important; opacity: 0 !important;}
Visually HiddenのスタイルはAmpで利用されているスタイルを参考にしています。縦横幅が1pxの実装だと環境によっては読み上げてもらえない可能性があるらしい?(未検証)。
SVGのtitle要素について
title要素はaria-labelledbyで紐づければ読み上げ対応できる
冒頭で紹介した記事では文中に「インタラクティブな要素内のsvg
要素のtitle
要素は、ブラウザとスクリーンリーダーの組み合わせによっては読み上げられないことがあります」とあり、実際にVoice OverとSafariの組み合わせで読み上げられなかったとありましたが、こちらに関してはaria-labelledby
で紐づけを行っていれば読み上げ対応できます。
実際にVoice OverとSafariの組み合わせで確認しましたが、私の環境では読み上げられていることを確認しました。

title要素はツールチップが表示される
インラインSVGの代替テキストをtitle要素で実装した場合、ホバーでツールチップが表示されます。

通販サイトなどで導線がアイコンのみで表示されている際、たまに「これどういう意味だ?」ってアイコンあったりしませんか?
そういった場合にツールチップが表示されれば非常にありがたいなって思ってるので、主観になりますがツールチップが表示されるのはメリットだと思ってます。
title要素は機械翻訳対象にならない
title要素は機械翻訳対象になりません。aria-label
を翻訳してくれるChromium系のブラウザでもtitle要素の翻訳はされませんでした。translate="yes"
属性やlang="ja"
で言語を明確化しても翻訳されませんでした…。導線に使われているような確実にテキストを翻訳して伝えたいテキストについてはこの仕様だと困ります。
Visually Hiddenなテキストであれば翻訳対象になります。
ただし、英語表記のサービス名やブランド名のように翻訳されたら間違った表記になってしまうようなテキストに関してはこの仕様はありがたいかもしれません。例えばnoteというサービス名を含んだリンクを敢えて和訳にかけると「注記」と翻訳されますが、これでは意味合いが異なってしまいます。
title要素はページ内検索対象にならない
title要素はページ内検索でヒットしません。とは言え、img
要素のalt属性
も検索でヒットしませんし、Visually Hiddenなテキストは検索でヒットするものの可視化されません。
ページ内検索対象にならないというのはtitle要素特有のデメリットでは無いような気がします。
title要素は選択&コピーできない
title要素は選択&コピーの対象になりません。そもそもインラインSVG自体が選択できません。
Visually Hiddenなテキストであれば選択&コピー対象になります。
インラインSVGの中に選択&コピーされて嬉しいような文章がある場合はこの仕様だとデメリットになり得ます。
aria-labelは個人的に選択肢から外れる
冒頭の記事ではrole="img"
とaria-label
を付与するのが妥当とありましたが、個人的には選択肢から外れます。
aria-label
はSafariとFirefoxで翻訳対象にならず、選択&コピーができない問題があるためです。
まとめ
やっぱり重要な意味合いを持つSVG画像に関してはimg
要素で読み込んでalt
属性を付与することがやっぱり最善かなと思います。
インラインSVGに関してはVisually Hiddenなテキストを別途用意するのが一番メリットあるように感じます。理想としてはtitle要素を使いたいですが…。
この記事はあくまで私個人の見解です。