弁護士ドットコム株式会社 Creators’ blog

弁護士ドットコムがエンジニア・デザイナーのサービス開発事例やデザイン活動を発信する公式ブログです。

アクセシブルなドロップダウンメニューの構成

この記事は、弁護士ドットコム Advent Calendar 2024 の 2 日目の記事です。

こんにちは、弁護士ドットコムでクラウドサインというサービスのフロントエンドを実装している @RINYU_DRVO と申します。車とギターが大好きです。

昨年の Advent Calender は Go html/templateで書くHTMLメールのハマりどころと対処法 を投稿しました。

今年のテーマは「ドロップダウンメニュー」「アクセシビリティ」です。

この記事で伝えたいこと

  • ドロップダウンメニューをアクセシブルに実装する際の必要な要素や属性
  • それらの役割

背景

クラウドサインで実装しているドロップダウンメニューの中には、キーボードで操作できないものが存在します。

キーボードで操作ができない UI はアクセシビリティ上の問題があります。なぜならば、マウスなどのポインティングデバイスを使用できないユーザーにとっては利用が難しいためです。

そのため、ドロップダウンメニューの改修をしようとしています。

まずは、アクセシビリティの改善のために何が必要なのかを認識する必要があると思い、具体的に必要となる実装と、それらの具体的な役割をまとめました。

クラウドサインのアクセシビリティに関する取り組みは下記もご覧ください。

ウェブアクセシビリティ改善に向けた取り組み〜試験結果公開〜

イベント開催レポート:「出張!俺の電子契約」〜クラウドサインをアクセシビリティチェック〜

改修対象

下記画像のような汎用のドロップダウンメニューコンポーネントを改修対象とします。

メニューを閉じた状態 閉じたドロップダウンメニュー

メニューを開いた状態 開いたドロップダウンメニュー

この UI の動作は、ドロップダウンメニューを開閉する要素を押すと、メニューが表示されるようになっています。

構成の全体像

改善後のドロップダウンメニューは、簡素に表すとこのような要素で構成されることになります。

<!-- ドロップダウンメニューを開閉する要素 -->
<!-- button でもいいと思う -->
<a
  aria-haspopup="true"
  aria-expanded="true"
  href="#about"
>About</a>
<!-- ドロップダウンメニュー実体 -->
<ul
  role="menu"
  aria-label="About"
>
  <!-- メニューアイテム単体の枠 -->
  <li role="none">
    <!-- メニューアイテムの操作可能要素 -->
    <a
      role="menuitem"
      href="#overview"
    >Overview</a>
  </li>
  <!-- li 要素がメニューアイテム分続く -->
</ul>

参考:ARIA Authoring Practices Guide - Navigation Menubar Example

解説

アクセシブルなドロップダウンメニューの要素を構成する各属性についての解説です。

※解説内に掲載しているコードは解説用に省略したものであるため、それ単体では必要な属性が不足している場合があります。

role 属性

<ul role="menu">

要素がメニューコンテナとして識別されるようになります。

<a role="menuitem">Overview</a>

要素がメニュー項目として識別されるようになります。

menuitem ロールの要素にはアクセシブルな名前を与える必要がありますが、この場合は a 要素のテキスト内容が名前として使われます。

none

<li role="none">

この li 要素は暗黙の listitem ロールを持ちますすが、親要素である ul 要素のロールを list から menu に変更したため、listitem としては機能しません。ロールに none を指定することで、listitem でなくなったことを明示的に示しています。

aria 属性

aria-label

<ul
  role="menu"
  aria-label="About"
>

支援技術がメニューを読み上げる際の名前を定義します。

子要素に存在するメニュー項目が何のメニューに属しているかを支援技術に伝えています。

aria-haspopup

<a aria-haspopup="true">About</a>

要素に、これによって発生させるポップアップが存在することを示します。

aria-haspopup="menu" としないのは、発生するものがメニューであることはすでに menu ロールで示しているためです。

aria-expanded

<a aria-expanded="true">About</a>

メニューの開閉状態を示します。

結論

ドロップダウンメニューは role menumenuitem 属性を使って要素を構成し、aria-haspopup でメニューがあることを示してあげましょう。そうすることにより、支援技術にも UI の意図が伝わるものとなります。

なおメニューが入れ子になり 2 階層以上のドロップダウンとなる場合は、入れ子の入り口の menuitemaria-haspopup を設定したうえで、続けて menu を展開する形となります。

まとめ

今回はアクセシブルなドロップダウンメニューの構成について紹介しました。

ドロップダウンメニューをオリジナルで実装する場合や、既存のドロップダウンメニューをアクセシブルなものに改修する際は、ぜひこの記事を参考にしてください。