トピックを検索
キーボードやスクリーンリーダーで使えないカルーセル
トップページのカルーセルの矢印とドットがクリックしか受け付けないか、ボタンにしても、どのスライドを表示中か、スライドが変わったことを伝えません。
<div class="carousel-next"></div> 問題
キーボード利用者は1枚目以外のスライドを表示できません。矢印とドットを操作できるようになっても、スクリーンリーダー利用者には、どのスライドを表示中か、変わったことが伝わりません。
ある市立美術館のトップページは、3枚のスライドのカルーセルで始まります。秋の展覧会、金曜の夜間開館、会員の案内です。各スライドには見出し、1行の説明、リンクがあります。左右の矢印と下の3つのドットはクリックでスライドを変え、表示中のスライドのドットは塗りつぶされます。矢印とドットは、クリック処理を付けたdivとspanです。Tabを押すと、1枚目のスライドのリンクからページの次のリンクへ直接進むため、キーボード利用者には1枚目しか見えません。スクリーンリーダーは矢印もドットも読まず、塗りつぶしたドットは色でしかありません。マウス利用者がスライドを変えても、何も読み上げられません。
途中までしか直していないカルーセルもよくあります。矢印とドットが名前のある本物のボタンになっていれば、キーボードでスライドを変えられます。それでも、スクリーンリーダー利用者が「次へ」を押すと何も聞こえず、ドットでは「スライド2、ボタン」と読まれるだけで、どれが表示中かは伝わりません。操作はできても、何が表示されているかは分からないままです。
達成基準2.1.1「キーボード」は、マウスでできることはすべてキーボードでもできることを求めています。2枚目や3枚目のスライドを表示する方法は、フォーカスを受けないdivやspanのクリックだけのため、キーボードではまったくできません。達成基準4.1.2「名前(name)・役割(role)及び値(value)」は、操作に名前、役割、現在の状態があることを求めています。矢印とドットには名前も役割もなく、ドットはどのスライドが表示中かを色だけで示し、その状態は伝わりません。
矢印とドットをボタンにするだけでは足りません。表示中のドットは状態を色だけで示したままで、同じく4.1.2を満たしません。また、「次へ」を押すと、フォーカスはボタンにあるまま隣の内容が入れ替わるため、スクリーンリーダー利用者には何も聞こえず、押して何か起きたのか、今どのスライドにいるのかも分かりません。ARIA Authoring Practicesのカルーセルは、新しいスライドを控えめなライブリージョンで読み上げます。下の修正方法も同じようにしています。
カルーセルはトップページの最初にあり、2枚目以降には夜間開館と会員の案内があります。マウスを使えない人やドットが見えない人は、それがあることを知らないままになります。
10グループ中2グループに影響
divとspanで作った矢印とドットには役割がないため、axeが確認することはありません。この診断ツールは、次の条件をすべて満たすものを報告します。クラス名でカルーセル、スライダー、スライドショーと分かる要素の中にあり、prev、next、arrow、dot、bullet のようなクラス名を持ち、ポインターのカーソルが表示され、フォーカスを受けないものです。アクセシビリティ用のモジュールなしのSwiperの矢印や、古いバージョンのOwlとFlickityのドットがこれに当たりますが、サイトが別の名前を付けた矢印は見つかりません。矢印がアイコンだけのボタンの場合、axeは名前がないことを button-name として報告します。表示中のドットがそのことを伝えるか、新しいスライドが読み上げられるかは、どの確認でも分かりません。AIの修正は、divに role="button" と tabindex="0" を加えて終えることがよくあります。Tabでは止まりますが、EnterキーやSpaceキーを押しても何も起きません。役割のないdivに aria-label を付ける修正もよくありますが、多くのスクリーンリーダーはこれを無視します。aria-live="assertive" で「スライドが変わりました」と伝える修正は、読み上げを中断するうえ、何のスライドかも伝えません。
試してみる
Tabキーで2枚目のスライドを表示し、それが表示中だとスクリーンリーダーに伝わるか確かめてください。
「問題1」では、Tabキーは矢印とドットを飛ばします。「問題2」ではキーボードで操作できますが、下の欄を見てください。どのドットも表示中とは読まれず、「次へ」やドットを押しても新しいスライドは読み上げられません。
問題あり 修正できますか?
スクリーンリーダーの読み上げ:
(Tabでカルーセルへ移動するか、ドットをクリック)
修正方法
矢印とドットを名前のあるボタンにし、表示中のドットを示し、新しいスライドを読み上げます。
- 1矢印とドットはすべて、名前のあるHTML標準のbuttonにする。
- 2表示中のドットには aria-current を付け、見た目はその属性から描く。
- 3ボタンで表示したスライドは、フォーカスを動かさずに読み上げる。
クリックしか受け付けない矢印とドット
<div class="carousel"> <div class="slides"> <div class="slide"> <h2>紙と光</h2> <p>秋の展覧会、1月31日まで。</p> <a href="/exhibitions/paper-and-light">展覧会を見る</a> </div> <div class="slide" hidden> <h2>金曜は夜まで開館</h2> <p>展示室とカフェは21時まで開いています。</p> <a href="/visit">ご来館案内</a> </div> <div class="slide" hidden> <h2>会員になる</h2> <p>1年間入館無料。新しい展覧会をいち早くご覧いただけます。</p> <a href="/membership">今すぐ入会</a> </div> </div> <div class="carousel-prev"></div> <div class="carousel-next"></div> <div class="carousel-dots"> <span class="carousel-dot is-current"></span> <span class="carousel-dot"></span> <span class="carousel-dot"></span> </div></div><section class="carousel" aria-roledescription="カルーセル" aria-label="おすすめ"> <button type="button" class="carousel-prev"> <svg aria-hidden="true" focusable="false"><use href="#icon-previous"></use></svg> <span class="visually-hidden">前のスライド</span> </button> <button type="button" class="carousel-next"> <svg aria-hidden="true" focusable="false"><use href="#icon-next"></use></svg> <span class="visually-hidden">次のスライド</span> </button> <div class="slides" aria-live="polite"> <div class="slide" role="group" aria-roledescription="スライド" aria-label="3枚中1枚目"> <h2>紙と光</h2> <p>秋の展覧会、1月31日まで。</p> <a href="/exhibitions/paper-and-light">展覧会を見る</a> </div> <div class="slide" role="group" aria-roledescription="スライド" aria-label="3枚中2枚目" hidden> <h2>金曜は夜まで開館</h2> <p>展示室とカフェは21時まで開いています。</p> <a href="/visit">ご来館案内</a> </div> <div class="slide" role="group" aria-roledescription="スライド" aria-label="3枚中3枚目" hidden> <h2>会員になる</h2> <p>1年間入館無料。新しい展覧会をいち早くご覧いただけます。</p> <a href="/membership">今すぐ入会</a> </div> </div> <div class="carousel-dots"> <button type="button" class="carousel-dot" aria-current="true"><span class="visually-hidden">スライド1</span></button> <button type="button" class="carousel-dot"><span class="visually-hidden">スライド2</span></button> <button type="button" class="carousel-dot"><span class="visually-hidden">スライド3</span></button> </div></section>この方法を選ぶ理由:まずHTMLの要素を使う
矢印とドットは click にしか反応せず、Tabの移動先にならず、名前も役割もありません。表示中のドットは色を変えるクラスで示しているだけで、新しいスライドはスクリーンリーダーに何も伝えずに前のスライドと入れ替わります。
Tabはすべての矢印とドットに届き、EnterキーとSpaceキーで押せるため、キーボードですべてのスライドを表示できます。それでも、スクリーンリーダーの利用者にとっては何も変わりません。表示中のドットはクラスで示しているだけのため、そのスライドが表示中かどうかに関係なく「スライド2、ボタン」と読まれます。スライドはただのdivの中にあるため、「次へ」やドットを押しても、何も伝えずにスライドが変わります。スクリーンリーダー利用者はカルーセルを操作できても、どのスライドが表示されているかは分かりません。
矢印とドットは本物のボタンのため、Tabで届き、EnterキーとSpaceキーで押せます。キー操作を自分で書く必要はなく、それぞれに名前があります。矢印はスライドより前にあるため、キーボードで先に届きます。表示中のドットには aria-current="true" があるため、スクリーンリーダーはそこで「現在の項目」と伝えます。塗りつぶした見た目もその属性から描くため、見た目と読み上げが食い違うことはありません。控えめなライブリージョン(polite)により、矢印やドットを押したスクリーンリーダー利用者には、フォーカスを動かさずに新しいスライドが読み上げられ、スライドのラベルで3枚中の何枚目かが伝わります。
ドットは必須ではありません。矢印で十分な場合は、ドットを今の位置を示す絵として残し、aria-hidden="true" を付けてクリック処理は付けません。そうすれば、キーボードで届かないものは残りません。クリックできるまま残す場合は、それぞれにボタンに必要なものをすべて持たせます。
- 隠したテキストか
aria-labelによる名前。ここでは「スライド1」。 - 24×24ピクセル以上のターゲット。12ピクセルのドットでは足りません。
- 見えるフォーカス表示と、背景に対して3:1のコントラスト。
- 表示中のドットの
aria-current="true"。見た目はクラスではなくこの属性から描きます。
読み上げは短く、控えめにします。ライブリージョンはスライドそのもの、つまりラベルと内容を読み上げるため、「スライドが変わりました」のような別のメッセージは要りません。aria-live="assertive" にすると、スクリーンリーダーが読んでいる途中の内容を中断します。
aria-roledescription は、スクリーンリーダーが領域と各スライドを何と呼ぶかを変えるため、この2つにだけ、ページの言語で付けます。英語なら「carousel」と「slide」、日本語なら「カルーセル」と「スライド」です。「3枚中1枚目」というラベルで今どこにいるかが伝わり、スライドの見出しで何についてのスライドかが伝わります。
スワイプは残してもかまいませんが、タッチ画面のための補助であり、スライドを変える唯一の方法にはしません。多くのカルーセルのライブラリには、Swiperのa11yモジュールのようなアクセシビリティのオプションがあります。オンにしたうえで、実際に何をするかを下の手順で確認します。複数の商品カードを一度に見せる商品カルーセルにも、同じことが当てはまります。矢印は名前のあるボタンにし、矢印で見えるようになったものは読み上げます。
AI コーディングアシスタントで修正しますか? このガイドを Markdown で取得
修正の確認
マウスを使わない4つの確認
確認方法: キーボード、スクリーンリーダー、強制配色
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。カルーセル、スライド、ライブラリを変更した際は、再度確認します。
制限
このサンプルは、どのアプリケーションでも同じ結果になることを保証するものではありません。扱うのは、矢印とドットに届くか、何を伝えるかです。自動で切り替わるカルーセルには、止める手段も必要です(2.2.2)。一時停止できない、流れる文字、カルーセル、アニメーションを参照してください。スライドにフォーカスが入ったときに切り替えを止める方法も扱っています。各スライドの文字と背景の写真のコントラスト(1.4.3)と、情報を伝える写真の代替テキストも、別に確認が必要です。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
コードを更新しても、使いやすさを保つために
ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。