こんにちは、音ゲーマーのKen@未難1です。
今回はCSSだけを使ったドロップダウンメニューの作り方を紹介します。
簡単な記述で便利な部品が作れるので、是非お試し下さい。
ベースHTML
このHTMLをベースにしてスタイルを設定していきます。スタイルなしで表示するとこんな感じ。ただの2階層のリストです。これを元に、「メニュー」の部分をマウスで触ると項目が表示されるようにします。
大枠のスタイル
ul, li { list-style: none; margin: 0; padding: 0; } .dropdown_container{ display: inline-block; background-color: #fff; border: solid 1px black; }
ul要素やli要素にはブラウザのデフォルトのスタイルで list-style, margin, padding が設定されています。今回は見た目の調整の邪魔になってしまうので、それぞれnone, 0, 0を指定して無効化します。
そして、dropdown_containerクラスが今回のメイン。dispaly: inline-box を設定し、背景色とボーダーを設定しました。
メニューの中身のレイアウト
ul, li { list-style: none; margin: 0; padding: 0; } .dropdown_container{ display: inline-block; background-color: #fff; border: solid 1px black; position: relative; } .dropdown_container > ul{ position: absolute; top: 100%; left: 0; width: 300px; border: solid 1px black; background-color: #eee; }
メニューの中身のレイアウトを設定しました。.dropdown_container > ul というセレクタを指定することでdropdown_containerクラスの子要素のul要素を指定しています。重要なのは position: absolute; の部分で、これを指定することで、要素の表示位置を自由に指定することが出来ます。
さらに、親要素はサイズを決定する際にabsolute な子要素を無視します。どういうことかというと、「メニュー」を囲っている黒線が一つ前のキャプチャでは長い名前の項目につられて横に伸びていたのが、今回は伸びなくなっているのがわかると思います。また、見た目ではわかりづらいですが縦方向にも伸びなくなっており、今の状態では「メニュー」の文字の周囲だけを囲った状態になっています。
そして top: 100%; left: 0; の部分で表示位置を指定していますが、どこを基準にどう設定されているか分かるでしょうか?
実は、親要素、つまり「メニュー」の左上隅が top: 0; left: 0; の位置になります。これはdropdown_containerクラスのスタイルに position: relative; を追加しているのが重要です。absolute な要素の基準位置は、その要素から見て一番近い、relative または absolute な要素を位置決めの基準にします。
今回は親要素に position: relative; を指定したので、これが基準になりました。そして top: 100%; の指定により、「メニュー」の高さ分だけ下に移動、結果的にすぐ下に張り付いて表示されるようになっています。
マウスを合わせると表示されるようにする
ul, li { list-style: none; margin: 0; padding: 0; } .dropdown_container{ display: inline-block; position: relative; background-color: #fff; border: solid 1px black; } .dropdown_container > ul{ position: absolute; top: 100%; left: 0; width: 300px; border: solid 1px black; background-color: #eee; height: 0; overflow: hidden; } .dropdown_container:hover > ul{ height: auto; }
いよいよです。マウスで触った場合のスタイルを設定しましょう。
まず、先ほどのスタイルに height: 0; overflow: hidden; を追加します。これで要素の高さ0、はみ出した部分は非表示となり、メニューの中身が表示されなくなりました。続いて、アニメーションするボタンでも使った、hover擬似クラスを使ってマウスで触った場合のスタイルを設定します。
今回は .dropdown_container:hover > ul のように指定することで、dropdown_containerにマウスが触れると、中身のul要素を表示するという指定をしています。height: auto; で高さの設定を通常に戻すことで要素を表示しています。
見た目の調整
ul, li { list-style: none; margin: 0; padding: 0; } .dropdown_container{ display: inline-block; position: relative; background-color: #fff; border: solid 1px black; } .dropdown_container > ul{ position: absolute; top: 100%; left: 0; width: 300px; background-color: #eee; height: 0; overflow: hidden; border: none; } .dropdown_container:hover > ul{ height: auto; border: solid 1px black; } .dropdown_container a { display: block; color: black; text-decoration: none; } .dropdown_container a:hover { background-color: #fcc; }
うまく開閉できましたが、閉じた状態で横線が表示されてしまいました。これはボーダーを表示するための border: solid 1px black; が閉じた状態でも有効になっているのが原因です。
これを回避するため、マウスで触れた場合のスタイルだけにボーダーを設定しました。ついでにメニューの中のリンク部分もスタイルを設定しましょう。color:black; text-decolation:none; で文字の色と下線のスタイルを変更しました。
また、通常はリンクの文字の部分しかクリックできませんが、display: block; を指定することで横幅が親要素いっぱいに広がり、クリックしやすくなります。ついでにここにもhover擬似クラスを指定して、マウスで触れると色が変わるようにしました。
これで、ドロップダウンメニューの完成です!
(おまけ) 開閉のアニメーションを設定したい
せっかくなので、前のやつみたいにtransitionを使って、開閉するときにしゅるしゅるっとアニメーションさせたい… ところなんですが、残念ながら transition: height 500ms; などと設定してもアニメーションしてくれません。なぜかというとtransitionによってアニメーションできるのは数値または色であり、height: auto; のautoは数値ではないからです。
jQueryなどでJavascriptを使えば比較的簡単に可能ですが、CSSだけではちょっと難しいです。いろいろな工夫によって一応可能ですが、内容が難しくなってしまうので今回は割愛します。 興味のある方はチャレンジしてみましょう。
いかがでしたでしょうか?
今回はabsoluteとhover擬似クラスの組み合わせによってドロップダウンメニューを作成する方法を紹介しました。今回のように、擬似クラスをうまく利用することでJavascript無しでも動きのある部品を作成することが可能です。
ぜひ、お試し下さい。
それでは。