<a href> の中を構造化すると iOS の VoiceOver ではリンクが分割されてしまう

年明け早々こんな記事が。

曰く、<a href="#">text <code>code</code> text</a> のようにリンクの中を構造化すると、iOS の VoiceOver ではリンクが分割されて読み上げられてしまうとのこと。手元の iPad (iPadOS 18.2.1) で試してみたところ、確かにそのようになってしまいました。

当該のユーザーにとっては事実上以下のマークアップと同義になってしまうわけで、ちょっとマズい状況です。

<a href="#">text</a> <a href="#"><code>code</code></a> <a href="#">text</a>

ただし <span> など一部の要素は問題なく、さらに role=none を付与することでも回避可能とのこと。すなわち、<a href> の中で <code> 要素等を使いたければ

<a href="#">text <code role="none">code</code> text</a>

あるいは

<style>
/* https://html.spec.whatwg.org/multipage/rendering.html#phrasing-content-3 */
.code {
	font-family: monospace;
}
</style>

<a href="#">text <span class="code">code</span> text</a>

などとすればとりあえずは解消します。

元記事では role=generic な要素であれば問題ないと書かれていますが、私の環境で確認したところ <em> 要素(role=emphasis)や <img> 要素(role は条件により様々)も大丈夫でした。1つのリンクの中にテキストと画像を両方含めるケースはかなり多いので、これを気にしなくてよいのは不幸中の幸いですね。一方で <dfn> 要素(role=term) や <cite> 要素(No corresponding role)はダメで、条件がよく分かりません。

特定環境のバグのためにマークアップを変えるのはナンセンスに思うのですが、Web の根幹たるハイパーリンク周りのバグとあってはそのユーザーにとっては致命的なことで、しかも iOS にデフォルトでインストールされた VoiceOver ですから「他のスクリーンリーダーを使えばよい」と無下にする判断もしにくいことでしょう。本ブログでもタイトルに <code> 要素を使った記事は多く、それがリンクになっている箇所では影響が出てしまっています。バグ報告はされているのですぐに直ればよいのですが、長期化した場合どうしたものか悩みますね……。