前回メニューを横並びにしましたが、そのメニューに子要素があった場合の話です。
例えば「カテゴリー一覧」というメニューがあって、そこにマウスカーソルを当てると下に各カテゴリーのリンク一覧がピロッって出てくるものです。
これがあればメニューをシンプルに整理することが出来、利用者も簡単に目的のページを見つけることが出来ます。
オシャレなデザインのドロップダウンメニューもありますが、今回は可能な限りシンプルに作成することで、ドロップダウンを作成するCSSの説明を分かりやすくしようと思います。
CSSでドロップダウンメニュー作成方法
対応する場所は上の画像の赤枠の部分です。
まず、メニュー部分のHTMLをこのように変更しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<nav id="headernav"> <ul class="gmenu"> <li> <a href="https://dev-lib.com">メニューA</a> <ul> <li><a href="https://dev-lib.com">メニューA-1</a></li> <li><a href="https://dev-lib.com">メニューA-2</a></li> <li><a href="https://dev-lib.com">メニューA-3</a></li> <li><a href="https://dev-lib.com">メニューA-4</a></li> </ul> </li> <li> <a href="https://dev-lib.com">メニューB</a> <ul> <li><a href="https://dev-lib.com">メニューB-1</a></li> <li><a href="https://dev-lib.com">メニューB-2</a></li> <li><a href="https://dev-lib.com">メニューB-3</a></li> <li><a href="https://dev-lib.com">メニューB-4</a></li> </ul> </li> <li> <a href="https://dev-lib.com">メニューC</a> <ul> <li><a href="https://dev-lib.com">メニューC-1</a></li> <li><a href="https://dev-lib.com">メニューC-2</a></li> <li><a href="https://dev-lib.com">メニューC-3</a></li> <li><a href="https://dev-lib.com">メニューC-4</a></li> </ul> </li> <li> <a href="https://dev-lib.com">メニューD</a> <ul> <li><a href="https://dev-lib.com">メニューD-1</a></li> <li><a href="https://dev-lib.com">メニューD-2</a></li> <li><a href="https://dev-lib.com">メニューD-3</a></li> <li><a href="https://dev-lib.com">メニューD-4</a></li> </ul> </li> <li> <a href="https://dev-lib.com">メニューE</a> <ul> <li><a href="https://dev-lib.com">メニューE-1</a></li> <li><a href="https://dev-lib.com">メニューE-2</a></li> <li><a href="https://dev-lib.com">メニューE-3</a></li> <li><a href="https://dev-lib.com">メニューE-4</a></li> </ul> </li> </ul> </nav> |
メニューの子要素は、親メニューの li タグの中に ul タグを作成し、その中の li タグに子メニューを作成します。
4行目、13行目などは、親メニューになります。ここはリンクで無くてもいいです。
次にCSSです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
/* メニュー */ ul.gmenu { margin: 0; padding: 0; background-color: #000000; } ul.gmenu > li { display: inline-block; padding: 5px; font-weight: bold; } ul.gmenu > li a { color: #ffffff; } ul.gmenu li:hover { background-color: #666666; } /* サブメニュー */ ul.gmenu ul { display: none; } ul.gmenu > li:hover ul { display: block; height: auto; position: absolute; background-color: #000000; padding: 5px; margin-left: -5px; } ul.gmenu ul > li { display: block; padding: 5px; } |
1~20行目までは、親メニューを作成したときに追加したCSSです。
8,14行目に > を追加し、親メニュー用のCSSが子メニューにも適用されないように修正しました。
22~39行目が、子メニュー用のCSSになります。
子メニュー対応したサンプルがこちらです。
詳細は次に解説します。
HTML・CSSの解説
ドロップダウンメニューを作成する上での肝は、擬似クラスと display プロパティ、position プロパティです。
その他微調整などもありますが、注目すべきポイントに絞って解説します。
擬似クラスでオンマウス時のみCSSを適用
CSSには擬似クラスというものがあります。今回使った :hover のようなものです。
他にもたくさんありますが割愛します。
:hover はセレクタで指定したHTML要素の上にマウスカーソルが来たら発動する擬似クラスです。
18行目は、メニューの1項目の上にカーソルが来たら背景色をグレーに変更するCSSです。
1 2 3 |
ul.gmenu li:hover { background-color: #666666; } |
次のCSSを見てください。
1 |
ul.gmenu > li:hover ul {} |
ul.gmenu > li は、親メニューの項目だけを指定しています。
つまり、ul.gmenu > li:hover と書くことで、親メニューの項目にマウスカーソルが当たった場合になります。
そして、ul.gmenu > li:hover ul と書くことで、親メニューの項目にマウスカーソルが当たった場合の子メニュー(ul タグ)を指定することになります。
マウスカーソルがあたった場合の表示・非表示切り替えは次に説明します。
display プロパティで表示・非表示を切り替える
1 2 3 |
ul.gmenu ul { display: none; } |
そして、display: none; で非表示にする設定になります。まるで元々そんなHTML記述は無かったかのように扱われます。
これで初期状態は子メニューを全て非表示にするということです。
次に、28行目を見てください。
display: block; は、値が block になっています。HTMLの表示形式にはブロック要素、インライン要素、テーブル関連、その他がありますが、その内のブロック要素にするということです。
一部の文章や画像を指定する場合にはインライン要素として扱いますが、メニューのようにエリアを指定する場合はブロック要素を使います。
そして、1行上のセレクタ ul.gmenu > li:hover ul で親メニューの項目にマウスカーソルがあたっている状態の子メニューを指定しているため、親メニューの項目にマウスカーソルがあたった時に子メニューを表示するということになります。
position プロパティで表示位置を固定する
position (ポジション)プロパティには、absolute や relative、fixed などがあります。
position プロパティは、表示位置を指定することが出来ます。
そして、absolute は表示位置を基準位置から指定することが出来ます。
top: 0; left: 0; をCSSで指定すると画面の一番左上に表示されるようになります。
今回は位置の指定は何もしていませんが、何も指定しないと元の位置に表示されます。
position の指定をしないと、通常のHTMLで指定された場所に表示されます。
つまり、親メニューの項目の隣くらいの場所です。ブロック要素の場合は親メニュー項目のすぐ下になります。
absolute のもう一つの効果は、元のHTMLを無視して、まるでレイヤーを分けたように重ねて指定した場所に表示出来ることです。
これで子メニューを表示した際に元のデザインが崩れることを防げます。
ちなみに、relative は表示位置の基準を固定します。
fixed は、absolute と似ているのですが、fixed で指定した場合は画面をスクロールさせてもその場所から動きません。
位置の微調整
33行目に、margin–left: –5px; という記述があります。
これは親メニューの項目に padding: 5px; を指定しているため、子メニューが5px右にずれて表示されてしまうので、子メニューの表示位置を左に5pxずらしました。
これにより、親メニュー項目の真下に子メニューを表示できます。
もし、分からなければ実際に動かしてみて、margin の指定を削除して表示させてみてください。
真似して疑問点を試すことは一番勉強になります。
その他色など
他は色やサイズを調整しているだけです。
お好みのデザインに変更して使ってください。
問題点
今回ドロップダウンメニューの対応をしましたが、問題点があります。
それは、フッターのメニューにも同様CSSが適用されるため、画面の一番下を突き抜けてドロップダウンされてしまうことです。
これは上にドロップダウンしたほうがいいですね!
(・・・上にドロップダウンて変な日本語ですね。白い黒板みたいな。)
プルアップって言うみたいです。次回はフッターのメニューを修正します。
まとめ
ドロップダウンメニュー如何でしたか?
擬似クラスと display プロパティ、position プロパティは通常の開発の中でもかなり使いますのでしっかり理解してください。
使い方も様々ですので、用途に合わせて今後紹介していこうと思います。
大変分かりやすい解説、ありがとうございました!大変勉強になりました。
cssでサブメニューの表示・非表示の挙動がよく分かりました。
ーーーー
こちらの記事を拝見するまでは、
「メインメニューにカーソルを当てて、サブメニューを表示させてから、
カーソルをサブメニューに移動したら、表示させたサブメニューが消えちゃうんじゃないか?」
との疑問がありましたが、
ul.gmenu > li:hover のには、 子メニューのが内包されているので、
サブメニューにカーソル移動しても、 ul.gmenu > li:hover されている状態が継続しているとみなされ、
結果、 display: none; されないんだな と分かりました。
ーーーー
まだまだ学習中で、わからない点もありますが、他の記事も拝見させていただき、学習を継続したいと思います!
改めて、記事作成いただきありがとうございました。