メインコンテンツまでスキップ

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

Web Topics

最近アイコンボタンのアクセシブルな名前はボタンが持つべきかアイコンが持つべきかという記事を読んで、SVGの代替テキストについて改めて考えさせられたので自分なりの考えをまとめました。

一番確実な方法はimg要素で読み込んでalt属性を付与することだと思いますが、CSSで装飾を変えられるインラインSVGの利点を捨てるのも難しいのでインラインSVGにどうやって代替テキストを含めるか?のみに焦点を当てていきます。

自分の中での結論

先に結論から伝えますと、理想を言えば svgの中にtitle要素を含み、role="img"titleと紐づけたaria-labelledbyで実装する」 のがベストだと思います。ただし、この方法では不都合な点がいくつか孕んでいるので現実は冒頭で紹介した記事の2.で触れられているような 「Visually Hiddenなテキストをsvgに隣接し、svgaria-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>
  • svgtitle要素を含み、そこで代替テキストを指定
  • 「画像」と読み上げてもらうためにrole="img"を指定
  • svgの代替テキストを読み上げてもらうためにtitlesvgaria-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="u-visually-hidden">新しいウィンドウが開きます</span>
.u-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の組み合わせで確認しましたが、私の環境では読み上げられていることを確認しました。

Voice OverとSafariの組み合わせで表示された読み上げのスクリーンショットです。「閲覧済み、リンク、note、新しいウィンドウが開きます」と読み上げられています。

title要素はツールチップが表示される

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

title要素を含めたSVGにホバーをあてた際のスクリーンショットです。「Zenn」とツールチップが表示されています。

通販サイトなどで導線がアイコンのみで表示されている際、たまに「これどういう意味だ?」ってアイコンあったりしませんか?

そういった場合にツールチップが表示されれば非常にありがたいなって思ってるので、主観になりますがツールチップが表示されるのはメリットだと思ってます。

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要素を使いたいですが…。

この記事はあくまで私個人の見解です。