スマホではtoggle、PCではマウスオーバーでドロップダウンができるナビゲーションを作るCSSとスクリプト

スマホではハンバーガーボタンをタップでナビゲーションメニューが表示されて、768px以上ではマウスオーバーでサブメニューが表示されるかたちのメニューをCSSとjQuery(プラグインなし)で作ってみました。
sponsored link
INDEX
ナビゲーションのデモ
このナビゲーションメニューの特徴としてはこのようなものになります。
- スマホではハンバーガーボタンを表示する(fixed)
- ハンバーガーボタンをタップするとナビゲーションがブラウザ一杯に表示される
- 768px以上になるとボタンが非表示になり、代わりにナビゲーションが表示される
- ナビゲーションをマウスオーバーするとサブナビゲーションがドロップダウンで表示される
ブラウザのウィンドウ幅を動かすとナビゲーションが切り替わっているのが分かると思います。
See the Pen toggle&hoverMenu by ManabuYasuda (@gaku) on CodePen.
jQuery
まず.prepend()
と.before()
メソッドでbody
タグの先頭とメインメニューの直前にidとクラスの付いたHTMLを挿入します(もちろんHTMLに直接記述してもOKです)。
4行目以降は.click()
イベントでボタンがクリックされたらナビゲーションを表示・非表示するようにしています。最終的な表示の制御はCSS側でしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$('body').prepend('<div id="grayLayer" class="grayLayer"></div>'); $("#dropDownMenu").before('<i id="iconBars" class="iconBars"></i>') .before('<i id="iconClose" class="iconClose"></i>'); $("#iconBars").click(function(){ $("#dropDownMenu li").show(200); $("#grayLayer").show(400); $("#iconBars").hide(); $("#iconClose").show(); }); $("#iconClose").click(function(){ $("#dropDownMenu li").hide(400); $("#grayLayer").hide(400); $("#iconClose").hide(); $("#iconBars").show(); }); |
HTML
HTMLはul
要素にdropDownMenu
というidとクラスをつけておきます。サブメニューとしてリストを入れ子にして記述しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<header class="l-header"> <div class="l-container"> <nav class="l-navigation"> <ul id="dropDownMenu" class="dropDownMenu"> <li><a href="#">mainMenu 1</a> <ul> <li><a href="#">subMenu 1-1</a></li> <li><a href="#">subMenu 1-2</a></li> <li><a href="#">subMenu 1-3</a></li> </ul> </li> <li><a href="#">mainMenu 2</a> <ul> <li><a href="#">subMenu 2-1</a></li> <li><a href="#">subMenu 2-2</a></li> <li><a href="#">subMenu 2-3</a></li> </ul> </li> <li><a href="#">mainMenu 3</a></li> </ul> </nav> </div> </header> |
CSS
長いですが、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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
html, body { height: 100%; margin: 0; padding: 0; } .grayLayer { display: none; position: fixed; top: 0; left: 0; z-index: 100; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.8); } .l-header { margin: 0 0 1em; height: 44px; } .l-header:after { content: ""; display: block; clear: both; } .iconBars { display: block; position: fixed; top: 15px; right: 15px; height: 44px; cursor: pointer; } .iconBars:before { font-family: 'FontAwesome'; content: "\f0c9"; display: inline-block; padding: 7px 9px; color: #333; background-color: #fefefe; font-size: 30px; line-height: 1; font-style: normal; } .iconClose { display: none; position: fixed; top: 15px; right: 15px; z-index: 1000; padding: 23px; cursor: pointer; } .iconClose:before, .iconClose:after { content: ""; position: absolute; top: 50%; background-color: #fff; transform: rotate(45deg); -webkit-transform: rotate(45deg); } .iconClose:before { width: 2px; height: 30px; margin-top: -14px; } .iconClose:after { width: 30px; height: 2px; margin-left: -14px; } .dropDownMenu { position: fixed; top: 80px; right: 0; left: 0; z-index: 1000; margin: 0 auto; padding-left: 0; font-size: 1.2em; list-style-type: none; } .dropDownMenu li { display: none; position: relative; text-align: center; } .dropDownMenu li a { display: block; height: 44px; line-height: 44px; font-weight: 600; color: #fff; text-decoration: none; } .dropDownMenu li a:hover { color: lightcoral; } .dropDownMenu li:hover ul li { overflow: visible; height: 44px; } .dropDownMenu li ul { padding-left: 0; font-size: .8em; list-style: none; } .dropDownMenu li ul li { width: 100%; } @media screen and (min-width: 768px) { .l-navigation { float: right; } .iconBars { display: none !important; } .dropDownMenu { display: block; position: initial; height: 44px; font-size: 1em; } .dropDownMenu li { float: left; display: block !important; } .dropDownMenu li a { padding: 0 2em; color: initial; background-color: #fff; } .dropDownMenu li a:hover { color: initial; } .dropDownMenu li ul { position: absolute; top: 100%; left: 0; } .dropDownMenu li ul li { overflow: hidden; height: 0; transition: .4s; } .dropDownMenu li ul li a { color: #fff; background-color: #333; border-top: 1px solid #888; } .dropDownMenu li ul li a:hover { color: #fff; background-color: #666; } } .l-container { max-width: 960px; margin-left: auto; margin-right: auto; padding: 0 15px; } |
ブラウザいっぱいの黒いレイヤー
ハンバーガーボタンをクリックした時にLightboxのようにブラウザ全体を黒い透明なレイヤーでおおいます。grayLayer
がブラウザすべてに配置されるようにhtml
とbody
要素にheight:100%;
を指定しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
html, body { height: 100%; margin: 0; padding: 0; } .grayLayer { display: none; position: fixed; top: 0; left: 0; z-index: 100; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.8); } |
ハンバーガーボタンとキャンセルボタン
iconBars
はFont Awesomeのアイコンフォント、iconClose
は疑似要素を使ってアイコンを表示しています。アイコンはheight:44px;
になるように指定しています。それぞれposition:fixed;
でブラウザに対しての絶対位置を指定して固定させています。
iconBars
をタップするとナビゲーションの表示、iconClose
をタップすると非表示になるようにjQueryで指定しています。
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 |
.iconBars { display: block; position: fixed; top: 15px; right: 15px; height: 44px; cursor: pointer; } .iconBars:before { font-family: 'FontAwesome'; content: "\f0c9"; display: inline-block; padding: 7px 9px; color: #333; background-color: #fefefe; font-size: 30px; line-height: 1; font-style: normal; } .iconClose { display: none; position: fixed; top: 15px; right: 15px; z-index: 1000; padding: 23px; cursor: pointer; } .iconClose:before, .iconClose:after { content: ""; position: absolute; top: 50%; background-color: #fff; transform: rotate(45deg); -webkit-transform: rotate(45deg); } .iconClose:before { width: 2px; height: 30px; margin-top: -14px; } .iconClose:after { width: 30px; height: 2px; margin-left: -14px; } |
スマホ向けナビゲーション
スマホでのナビゲーションではハンバーガーボタンの位置を固定させるので、ナビゲーションもposition:fixed;
で絶対位置に指定しておきます。z-index
はgrayLayer
より高く指定しておかないと触れなくなってしまうので注意します。
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 |
.dropDownMenu { position: fixed; top: 80px; right: 0; left: 0; z-index: 1000; margin: 0 auto; padding-left: 0; font-size: 1.2em; list-style-type: none; } .dropDownMenu li { display: none; position: relative; text-align: center; } .dropDownMenu li a { display: block; height: 44px; line-height: 44px; font-weight: 600; color: #fff; text-decoration: none; } .dropDownMenu li a:hover { color: lightcoral; } .dropDownMenu li:hover ul li { overflow: visible; height: 44px; } .dropDownMenu li ul { padding-left: 0; font-size: .8em; list-style: none; } .dropDownMenu li ul li { width: 100%; } |
768px以上
768px以上になるとボタンが非表示になり、ナビゲーションだけが表示されます。スマホでナビゲーションを表示したままになっていると表示がおかしくなってしまうので(スタイル属性が残ったままになるため)いくつか!important
を指定しています。
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 |
@media screen and (min-width: 768px) { .l-navigation { float: right; } .grayLayer, .iconBars, .iconClose{ display: none !important; } .dropDownMenu { display: block; position: initial; height: 44px; font-size: 1em; } .dropDownMenu li { float: left; display: block !important; } .dropDownMenu li a { padding: 0 2em; color: initial; background-color: #fff; } .dropDownMenu li a:hover { color: initial; } .dropDownMenu li ul { position: absolute; top: 100%; left: 0; } .dropDownMenu li ul li { overflow: hidden; height: 0; transition: .4s; } .dropDownMenu li ul li a { color: #fff; background-color: #333; border-top: 1px solid #888; } .dropDownMenu li ul li a:hover { color: #fff; background-color: #666; } } |
ちなみにドロップダウンはサブメニューの高さを0にしておいて、メインメニューにマウスオーバーされたら高さを出すようにして表現しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
.dropDownMenu li:hover ul li { overflow: visible; height: 44px; } @media screen and (min-width: 768px) { .dropDownMenu { height: 44px; } .dropDownMenu li ul { position: absolute; top: 100%; left: 0; } .dropDownMenu li ul li { overflow: hidden; height: 0; transition: .4s; } } |
参考にしたエントリー