更新日
アクセシビリティを考えたドロップダウンメニューを実装する
多くの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 MenuはAdobeのアクセシビリティチームが開発した、メガメニュー設置用プラグイン。tab
で親メニューを移動し、return
で子メニューを表示。子メニュー内は矢印キーや tab
、メニュー名の頭文字入力で移動できます。
同じプラグインを使った別のデモページでは、上記デモより頭文字入力での移動(子ページ表示時に「F」を押すと「Faculty」メニューがフォーカスされる等)がわかりやすく表現されています。
メガメニューのように、メニューの数が多くなればなるほど構造が複雑になってしまいます。プラグインを使って簡単に実装できるのはありがたいですね!ナビゲーションメニューは Web ページを操作する上で重要な要素のひとつ。様々な角度からより使いやすく、アクセスしやすいメニューの実装を考えていきたいです。