🤬

dl/dt/ddのスクリーンリーダーの読み上げをなんとかする

2023/09/03に公開

期待と異なる読み上げ

スクリーンリーダーを使ったことがある開発者ならご存知のとおり、dl要素、dt要素、dd要素の構造はスクリーンリーダーの読み上げにおいては期待と異なる挙動をします。おそらくは歴史的な経緯からそうなっているのだと思いますが、この挙動を理由にdl要素、dt要素、dd要素を使わないという選択をする開発者もいるようです。

現行のスクリーンリーダーの読み上げは概ね以下のような挙動をします。HTMLコメントの部分が読み上げられる内容とします。

<dl>
  <dt>りんご</dt>
  <!-- リスト 1/4 りんご -->
  <dd>バラ科の落葉高木</dd>
  <!-- リスト 2/4 バラ科の落葉高木 -->
  <dt>みかん</dt>
  <!-- リスト 3/4 みかん -->
  <dd>ミカン科の常緑低木</dd>
  <!-- リスト 4/4 ミカン科の常緑低木 -->
</dl>

挙動だけを見ると、次のコードと等価です。

<ul>
  <li>りんご</li>
  <!-- リスト 1/4 りんご -->
  <li>バラ科の落葉高木</li>
  <!-- リスト 2/4 バラ科の落葉高木 -->
  <li>みかん</li>
  <!-- リスト 3/4 みかん -->
  <li>ミカン科の常緑低木</li>
  <!-- リスト 4/4 ミカン科の常緑低木 -->
</ul>

まあ、 そんなことあってたまるか! と一番に思うでしょう。情報ツリー的には「りんご」と「みかん」の2つの情報に説明がぶら下がるかたちになるので、リストの項目が4つとして扱われ、用語と説明がフラットに並んでしまうのはどう考えてもおかしいです。

リストでなくしてみよう

こんな混乱を招きそうな読み上げをするなら、挙動そのものをなくしてしまうのはどうでしょうか。

<dl role="generic">
  <dt role="generic">りんご</dt>
  <!-- りんご -->
  <dd role="generic">バラ科の落葉高木</dd>
  <!-- バラ科の落葉高木 -->
  <dt role="generic">みかん</dt>
  <!-- みかん -->
  <dd role="generic">ミカン科の常緑低木</dd>
  <!-- ミカン科の常緑低木 -->
</dl>

role="generic"を指定することで、dl要素、dt要素、dd要素に暗黙的に定義されていたロールを無くします。無くすというより「特別な意味をもたない」という意味にします[1]。アクセシビリティツリーとしては以下と等価です。

<div>
  <div>りんご</div>
  <!-- りんご -->
  <div>バラ科の落葉高木</div>
  <!-- バラ科の落葉高木 -->
  <div>みかん</div>
  <!-- みかん -->
  <div>ミカン科の常緑低木</div>
  <!-- ミカン科の常緑低木 -->
</div>

これで、読み上げとしてはフラットになったわけですが、完全に間違っているリスト構造を伝えるよりもいくらかマシな状態になりました。

だったら最初から全部divでええやんかと思う方もいらっしゃるでしょうけど、まあ、そこはマークアッパーのエゴですかね。dl要素、dt要素、dd要素を使いたいんですよ。WAI-ARIAから見たらgenericだけど、HTMLから見たら説明リストは説明リストなのです。

role属性のフォールバックする性質を利用する

現在の段階では、この手法はスクリーンリーダーに効くことになりますが、これはこれでこのままにしておくとまずいです。というのも、スクリーンリーダーの説明リストの読み上げが改善されたときに、この手法のままだと、その恩恵を受けられなくなってしまうからです。

そこで考えたのが、role属性の「複数指定でき、先に書かれたものが優先的に採用され、後に書かれたものはフォールバックとして扱われる」という性質を利用することです。

<dl role="associationlist generic">
  <dt role="associationlistitemkey generic">りんご</dt>
  <!-- りんご -->
  <dd role="associationlistitemvalue generic">バラ科の落葉高木</dd>
  <!-- バラ科の落葉高木 -->
  <dt role="associationlistitemkey generic">みかん</dt>
  <!-- みかん -->
  <dd role="associationlistitemvalue generic">ミカン科の常緑低木</dd>
  <!-- ミカン科の常緑低木 -->
</dl>

associationlistassociationlistitemkeyassociationlistitemvalueはWAI-ARIAの最新の草案(バージョンは1.3に相当する)で登場している新しいロールです[2]。それぞれがdl要素、dt要素、dd要素に対応する予定になっています。

つまり、これらの新しいロールにスクリーンリーダーが対応していれば、dl要素、dt要素、dd要素にふさわしい読み上げをしてくれるはずです。しかし、現状のスクリーンリーダーはまだ対応していないので、genericが適用されさきほどのフラットな読み上げになります。

あくまで実験ということで

新しいロールに対応しているスクリーンリーダーは存在しないので完全に机上の空論ではあります。実際にdl要素、dt要素、dd要素にふさわしい読み上げがどうなるかはわかりません。今後のスクリーンリーダーの進化に期待するしかありません。新しいロールもまだ草案段階なのでなくなる可能性もありますし。

ただ、今回の実験でrole属性のフォールバックする性質を利用することで、ロールのグレースフルデグラデーションができそうだというのは発見でした。今後のWAI-ARIAの進化に期待しつつ、この性質を利用した実験をしてみるのも面白いかもしれません。

この実験はアクセシビリティカンファレンス福岡のウェブサイトで実際に採用しています。挙動を実際に確認したい方はスクリーンリーダーで閲覧してみてください。

https://fukuoka.a11yconf.net

もちろん、何度も言いますが、僕がこのサイトのオーナー兼マークアッパーなのでこれをやっているので、みなさんは実プロダクトや実案件では真似しないでね。

脚注
  1. role=nonerole=presentationだと完全に読み上げられなくなってしまうので注意です。 ↩︎

  2. 新しすぎるため、WAI-ARIAをサポートするチェッカーやリンターにもことごとく怒られます。 ↩︎

GitHubで編集を提案

Discussion