logo
コーディング

更新日

アクセシビリティを考えたドロップダウンメニューを実装する

多くのWebサイトに設置されているドロップダウンメニュー。うまくカテゴリー分けされていれば非常にわかりやすく、スペースも取らないので制作側からも愛されていますね。しかしアクセシビリティの観点から考えると、ちょっとやっかいな存在ではあります。マウスがうまく利用できないユーザーはキーボードを使ってページやリンクを移動しますが、ドロップダウンメニューは `tab` キーを使ってもサブメニューが表示されないのです。今回はこの問題を解決しようと思います!

こちらの Gif 画像のように、カーソルではなくキーボードの tab キーを使ってリンクを推移できるようにします。通常の HTML と CSS を使った設置方法だと隠されている子メニューが表示されないので、キーボード操作でもうまく表示するのが今回の目標です。ちなみにこのブログのナビゲーションメニューにはすでに実装済みです!

まずは通常のドロップダウンメニューを作成

親メニューにマウスカーソルを合わせると、子メニューが表示される通常のドロップダウンメニューを作成します。

HTML

ul リストを入れ子にしてメニュー階層を実装。子メニューのあるリストには menu-item-has-children、子メニューには sub-menu というクラスをつけます。また、メニューを包む nav タグには role 属性で navigation を与え、その要素がナビゲーションであることを印づけます。

<nav role="navigation">
  <ul>
    <li class="menu-item-has-children">
      <a href="#">Coding ▼</a>
      <ul class="sub-menu">
        <li><a href="#">CSS</a></li>
        <li><a href="#">HTML5</a></li>
        <li><a href="#">WordPress</a></li>
        <li><a href="#">jQuery</a></li>
        <li><a href="#">SVG</a></li>
      </ul>
    </li>
    <li class="menu-item-has-children">
      <a href="#">Design ▼</a>
      <ul class="sub-menu">
        <li><a href="#">Web Design</a></li>
        <li><a href="#">Fonts</a></li>
        <li><a href="#">Colour</a></li>
      </ul>
    </li>
    <li><a href="#">Tips</a></li>
    <li><a href="#">For Beginner</a></li>
  </ul>
</nav>

role は日本語で「役割」を意味し、各要素がどんな役割を持つのかを定義できます。文書構造に印をつけ、アクセシビリティの向上を図りましょう。navigation 以外にも以下の役割が用意されています。

  • application(アプリケーション)
  • banner(バナー・ヘッダー等)
  • complementary(補足・サイドバー等)
  • contentinfo(コンテンツ情報・フッター等)
  • main(メインコンテンツ)
  • search(検索機能)

CSS

親メニュー部分は、float: left; で横並びにさせるだけです。

/* 親メニュー - Parent nav */
nav > ul > li {
  position: relative;
  float: left;
  margin-right: 45px;
}
nav a {
  color: #0bd;
  text-decoration: none;
}
nav ul a:hover {
  color: #0090aa;
}

で、子メニューの部分は position: absolute; で表示位置を指定した後、opacity: 0;visibility: hidden; で隠しておきます。さらに transition: .5s; でふわっと表示できるようにしましょう。

/* 子メニュー - .sub-menu */
nav .sub-menu {
  position: absolute;
  width: 180px;
  background: #0bd;
  top: 30px;
  opacity: 0;
  visibility: hidden;
  transition: 0.5s;
}
nav .sub-menu a {
  color: #fff;
  padding: 10px 15px;
  display: block;
}
nav .sub-menu a:hover {
  color: #fff;
}

あとは親メニューにホバーした時に子メニューを opacity: 1; visibility: visible; で表示させればドロップダウンメニューの完成です。

/* ホバーで子メニュー表示 */
nav .menu-item-has-children:hover ul {
  opacity: 1;
  visibility: visible;
}
nav li.menu-item-has-children li a:hover {
  background: #0090aa;
}

こんな感じ。子メニューを含むメニューにカーソルをあわせると、子メニューが下に表示されます。よくあるドロップダウンメニューですね。

Tab キーでフォーカスした時に子メニューを表示

親メニューに tab でフォーカスを当てても、このままでは上記 Gif のように親メニューのリンク移動しかできません。:focus 擬似クラスを用いても、フォーカスしている要素が親メニューから子メニューに移ると動作しなくなります。ということでおなじみjQueryでフォーカスしている要素にクラスを与えて、あれこれ操作できるようにしましょう。

JavaScript

親メニューである .menu-item-has-children a と、子メニューである .sub-menu a にフォーカスすると、子メニューを包む ul.sub-menu に新たに focused というクラスを付与します。

$(function () {
  $(".menu-item-has-children a")
    .focus(function () {
      $(this).siblings(".sub-menu").addClass("focused");
    })
    .blur(function () {
      $(this).siblings(".sub-menu").removeClass("focused");
    });

  // サブメニュー用
  $(".sub-menu a")
    .focus(function () {
      $(this).parents(".sub-menu").addClass("focused");
    })
    .blur(function () {
      $(this).parents(".sub-menu").removeClass("focused");
    });
});

CSS

CSS ではホバー時と同様、フォーカスされた時に opacity: 1; visibility: visible; で子メニューが表示されるようにします。

nav .menu-item-has-children:hover ul,
nav .menu-item-has-children ul.focused {
  opacity: 1;
  visibility: visible;
}
nav li.menu-item-has-children li a:hover,
nav li.menu-item-has-children li a:focus {
  background: #0090aa;
}

完成!

tab でメニュー操作できるはずです!サンプル枠内の余白部分をクリックしてフォーカスがあたるようにした後、キー操作をお試しください!

ちなみに Mac の Safari・Firefox ではデフォルト設定のままだと tab 操作でリンクの移動ができないみたいです。Safari の場合は Safari の環境設定 → 詳細で「Tab キーを押した時に Web ページ上の各項目を強調表示」をチェックすれば利用できるようになります。

Firefox は Mac のシステム環境設定 → キーボード → ショートカットの「フルキーボードアクセス」で「すべてのコントロール」を選択します。素敵な tab キーライフを!

jQuery プラグイン「Accessible Mega Menu」

デモダウンロード
アクセシビリティを考慮したナビゲーションを設置するための jQuery プラグインもリリースされています。Accessible Mega MenuAdobeのアクセシビリティチームが開発した、メガメニュー設置用プラグイン。tab で親メニューを移動し、return で子メニューを表示。子メニュー内は矢印キーや tab 、メニュー名の頭文字入力で移動できます。

同じプラグインを使った別のデモページでは、上記デモより頭文字入力での移動(子ページ表示時に「F」を押すと「Faculty」メニューがフォーカスされる等)がわかりやすく表現されています。


メガメニューのように、メニューの数が多くなればなるほど構造が複雑になってしまいます。プラグインを使って簡単に実装できるのはありがたいですね!ナビゲーションメニューは Web ページを操作する上で重要な要素のひとつ。様々な角度からより使いやすく、アクセスしやすいメニューの実装を考えていきたいです。