こんにちは。やまぐちなな(@nana_winter_web )です。
ページ数が多いサイトで実装する機会が増えるドロップダウンメニュー。
個人的に、ドロップダウンメニューがhoverで開くよりも、クリックで開くほうが使いやすいなと感じます。
用語の定義
子メニュー | クリックもしくは、hoverしたら表示される部分のこと |
---|---|
トリガー | 子メニューを開くための要素(ボタンなど)のこと |
今回は、ヘッダー付近に配置されるグローバルナビゲーションを例に話を進めていきます。
PC時(1024pxくらい)は横並びのグローバルナビゲーション、それ以下ではハンバーガーメニューになる設定です。
ちなみに、この呼び方は個人的に使っているだけなので、「ドロップダウンメニューのトリガーが」と話しても通じるかどうかはわかりません。
hoverで開くときも、クリックで開くときもやっておきたいこと
開きそう感を出す
全部同じ見た目なのに、一部のみ子メニューが出てきたらびっくりするので、トリガーには矢印や三角をつけて、子メニューが出てきそう感を出します。
子メニューが画面からはみ出した場合はスクロールできるようにする
グローバルナビゲーションが画面に追従する場合、画面の高さが低かったり、子メニューの高さが高い場合、スクロールできないと下の方の要素がクリックできません。
不便なので、下の方の要素もクリックできるようにしておきましょう。
max-height
をいい感じに設定して、overflow-y:auto
を設定するだけです。
hoverで開くパターン
WAI-ARIAを無視するなら、子メニューをCSSで非表示にし、サービスの文字にマウスオーバーで子メニューを表示するのが一番シンプルな実装方法だと思います。
この場合のトリガーは、サービスとその子メニューを包んでいる要素です。
PCでマウスを使って操作する人しか考えないのであれば一番シンプルですが、いろいろ問題があります。
スマホやタブレットなどのタッチデバイス時に必要がある
hoverがないタッチデバイスのために、タップなどで開けるように対応する必要があります。
ハンバーガーメニューにして子メニューは開いたまま
子メニューの項目数が少なく、メニュー自体が開閉する場合(ハンバーガーメニューなど)は、子メニューの開閉機能を無くし、子メニューを開いたままにするのが楽に実装できます。
目的の項目にたどり着くためのタッチ数も減るので、階層がわかりやすい見た目にしておけば、使いやすい気がします。
小さい開閉ボタンをタッチデバイス時に表示する
子メニューの項目数が多いと、開いたままだと邪魔なので、PC時のトリガーの横(中)に小さい開閉ボタンを表示し、それをトリガーとして扱う方法もあります。
リンク(PC時のトリガー)の中に開閉ボタンが入れ子になっているような見た目になります。
PC時のトリガーはリンクなので、慎重な操作をするか、指がめっちゃ細いか、タッチペンを使っている場合でないと思わぬページ遷移が発生します。
横向きタブレットのときにどうするか
メディアクエリ的にはハンバーガーメニューではない、タッチデバイス(横向きタブレットなど)をどうするかも考える必要があります。
hoverできないからといって、子メニューを開いておくのは邪魔ですし、ドロップダウンメニューが複数ある場合は子メニューが重なってしまうこともあります。
JavaScript(以下JS)でタッチデバイスを判定して、ハンバーガーメニューにするのが楽ですが、画面サイズ的には小さめのPCと同じサイズなのでハンバーガーにしないほうが見た目も良いですし、個人的には使い勝手も良くなります。
親ページを経由して、子ページに行かせるのが無難なところかな。
キーボードで操作した場合の扱い
クリックで子メニューを開閉する場合に比べて、ひと手間必要です。
WAI-ARIAを導入しない場合、focus-within(対応状況 )とPolyfill を使えば、手軽に対応できそうです。
hoverで開くパターンの始めに埋め込んであるコードはこちらの方法で実装しています。
WAI-ARIAを導入する場合、focus-withinの仕組みを利用してJSで属性を切り替えるのが一番安定して動きそうな感じがします。
予期しないときに開閉が起こる
マウスが通るだけでメニューの開閉が起こるので、ナビゲーションの位置によっては予期しないときにメニューの開閉が起こってしまうことがあります。
解決策の候補は以下の2つです。
- メニューの位置を変える
- 数秒間マウスを乗せたときにメニューを開くようにする
メニューの位置は何らかの理由があってマウスの通り道に置いていると思うのですが、本当にその位置である必要はあるのか考えても良いと思います。
数秒後に開く場合で考えられる最悪のパターンは以下の感じ。
- マウスを乗せる
- 開かない
- クリックしたら良いのね
- なんかページ遷移したねんけど
ツールチップなどで「何秒間マウスを載せていると開きますよ」とお知らせすることで避けられると思いますが、そこまでしてhoverでドロップダウンメニューを開閉する必要があるのかは分かりません。
目的のページをクリックするために、慎重な操作が必要
最短距離で子メニューの要素をクリックしようとすると、トリガーの範囲を外れてしまいます。
子メニューの位置や形状によっては、最短距離で子メニューの要素をクリックしようとしても、トリガーの範囲を外れることはないのですが、クリックで開く場合に比べて慎重な操作が必要なことには違いありません。
クリックで開くパターン
button
要素などをトリガーにし、子メニューを開閉するのがシンプルな作り方です。
button
要素を使う場合は、属性にtype="button"
をつけないと、予定外の動作が起こる場合があります。
WAI-ARIAを導入するとスクリーンリーダーを利用しているユーザーにとってもわかりやすくなります。
JSがオフのユーザーのために、あえてa
タグでトリガーを実装し、親ページに遷移させるのも良さそう。
まとめ
いろいろ書いてきましたが、個人的にクリックで開くほうがより多くのユーザーにとって使いやすいのではないかなと思います。
システムの仕様上クリックにするのが難しいこともあったりしますし、そうした理由が説明できれば、どちらの手法をとっても良いと思います。
直帰率やページ遷移数などで比較している訳ではないので、そのあたりを調査した結果などがあればぜひ教えてください。