CSSでドロップダウンメニューを作るたぶん一番簡単な方法
サイトのコンテンツ量が増えてくるといくらメニューを整理しても、いや、むしろメニューを事細かに整理するほど、メニューツリーは深く複雑になっていきますよね。
ぼくが運営しているサイトでもそんなサイトが増えてきたので、グローバルナビ(HP上部で横並びに表示されているメニュー)にマウスをのせたときにサブメニューが出てくる、いわゆるドロップダウンメニューを実装しようと思ったんです。
ところがググっても良いサンプルが見つからない。高機能な他階層対応メニューや、jQueryを使ったサンプルなどはすぐ見つかったのですが、いやーそんなすごいのは求めてないんだよなぁ。
CSSは複雑になるとプログラム以上に読み解くのが困難になってくるので、数年後、記憶喪失になってもパッと見ただけでわかるくらいのシンプルなドロップダウンメニューが実装したい。
というわけで、ないものは作ろう精神で、軽く書いてみました。
尚、ぼくはデザイン方面はからきしなので変なところがあったらゴメンね。
CSSで作るドロップダウンメニュー
HTML部
<ul class="menu">
<li>
<a href="#">MENU1</a>
<ul>
<li><a href="#">SUBMENU1</a></li>
<li><a href="#">SUBMENU2</a></li>
<li><a href="#">SUBMENU3</a></li>
</ul>
</li>
<li>
<a href="#">MENU2</a>
<ul>
<li><a href="#">SUBMENU1</a></li>
<li><a href="#">SUBMENU2</a></li>
<li><a href="#">SUBMENU3</a></li>
</ul>
</li>
<li>
<a href="#">MENU3</a>
<ul>
<li><a href="#">SUBMENU1</a></li>
<li><a href="#">SUBMENU2</a></li>
<li><a href="#">SUBMENU3</a></li>
</ul>
</li>
</ul>
ザ・普通。
ul~liでメニューを定義して、クラス名は一番上のulにだけ付ける感じ。
親のULグループと子のULグループで別のクラス名を付けたほうがCSS側はわかりやすくなるだろうけど、そうするとサイトマップへ使い回ししたりするとき、面倒かなーと。
ほら、最近はヘッダーに横並びメニュー、フッターにサイトマップもどき、というデザインが流行りじゃないですか。
そうじゃなくても別ページにサイトマップ用意するときもul~liをコピペしてクラス名一箇所変更するだけで流用できるほうが便利かな、と。
CSS部
.menu {
list-style-type:none;
}
.menu > li {
display:inline-block;
border:1px solid gray;
position:relative;
}
.menu > li > ul {
display:none;
}
.menu > li:hover ul {
display:block;
position:absolute;
padding:0;
margin:0;
top:1.5em;
left:0;
list-style-type:none;
border:1px solid gray;
}
20行くらいで済んでるし、けっこうシンプルだと思うけど、どうでしょう。
表示例
ひとまず見た目は置いておいて、動きはごく普通のドロップダウンメニューになってないですかね?
あ、この段階ではまだPCでの表示しか考慮していません。
PCだとマウスがあるから、マウスを親メニューにのせたときに子メニューが出てくる、という動作が自然に出来るハズ。
解説
箇条書きでざっくりと解説しておきます。
- menu > liにdisplay:inline-block;を指定して横並び表示にする
- menu > liにposition:relative;を指定して、サブメニューの基準座標を設定
- menu > li > ul、つまりサブメニューはdisplay:none;を指定して非表示
- menu > li:hover ulは親メニュー上にマウスがホバーした(のせられた)ときにその下のul要素(サブメニュー)のスタイルを指定する書き方
- 表示されたサブメニューはposition:absolute;指定によって、親要素を起点としたtop:1.5em;left:0;の座標に置かれる
- サブメニューは親メニューと違って横並びではなく縦並びなのでdisplayはblock;
と、こんなもんでしょうか。
だいぶシンプルに出来たなーとは思うのですが、これスマホだとちょっと困るんですよねー。
PC表示だけドロップダウンメニュー、スマホの場合は親メニューをクリックして次のページでサブメニューを選ぶ、みたいなサイトも多くありますが、上述の作りだと、親メニューをタップしたときに一瞬サブメニューが表示された後、次ページに遷移しちゃう。かっこわるい。
CSSのメディアクエリ(@media)を使ってPCのときだけドロップダウンメニューを表示する…というのもアリかも知れませんが、あれって端末の横幅に応じて調整するので、タブレットPCはどうするんだって話もあります。
タブレットPCの場合、指でタップするだけでなく、普通にマウスつなげてる人だっているわけだし。
うん、やはりここはPCとスマホ、どちらも同じ動きをするドロップダウンメニューを作ってみましょう。
スマホでタップしたときにドロップダウンメニューが開くようにする
HTML部
<ul class="menu2">
<li>
<a href="javascript:void(0);">MENU1</a>
<ul>
<li><a href="#">SUBMENU1</a></li>
<li><a href="#">SUBMENU2</a></li>
<li><a href="#">SUBMENU3</a></li>
</ul>
</li>
<li>
<a href="javascript:void(0);">MENU2</a>
<ul>
<li><a href="#">SUBMENU1</a></li>
<li><a href="#">SUBMENU2</a></li>
<li><a href="#">SUBMENU3</a></li>
</ul>
</li>
<li>
<a href="javascript:void(0);">MENU3</a>
<ul>
<li><a href="#">SUBMENU1</a></li>
<li><a href="#">SUBMENU2</a></li>
<li><a href="#">SUBMENU3</a></li>
</ul>
</li>
</ul>
………………………親メニューのaタグの飛び先をjavascript:void(0)にしただけです。
CSS部
変更なし
…なのですが、寂しいのでサブメニューに影を付けてみました。
.menu > li:hover ul {
box-shadow:0px 15px 10px rgba(0,0,0,0.4);
}
表示例
解説
いやーまいったまいった。
最初、Aタグを廃止して、onclick時にJavaScriptでポップアップメニューを表示/非表示するように切り替えたりとかちょっとだけ複雑なことしてたんですよ。
ところが、よくよく考えてみたら、Aタグをスマホでタップした場合でもhoverは発生しているから一瞬サブメニューが表示されるわけで、それならAタグで画面遷移しないようにすれば良いだけじゃん、と気が付きました。
ということで、結局HTML部だけほんのり変更するだけでPCでもスマホでもドロップダウンメニューを表示できるようになりました。ちゃんちゃん。
ちなみに、javascript:void(0);がカッチョ悪いと感じる人もいるようなので、そういった方はhrefの指定を外して、CSSでaタグにcursor:pointer;を指定すれば良いでしょう。
まとめ
他階層だったりアニメーションしたりするかっちょいいドロップダウンメニューのサンプルはたくさん見つかったのですが、逆に低機能でぎりぎりまで削ぎ落としたサンプルが見つからなかったので自分で作ってみました。
あんまりテストしていないので参考になるかわかりませんが、どこかの誰かのお役に立てば幸いです。