jQueryで一歩先を行くハンバーガーメニューを実装する方法
まりぞーです(∩°ω°∩)
PCのときは横並びのレイアウトで、モバイル端末など画面が小さい場合はぬるりと動くハンバーガーに格納されるjQueryでレスポンシブなメニューを作ってみました。
以前作成した初心者向けのアコーディオンメニューはこちらです。
初心者でもすぐできるスマホ対応jQueryアコーディオンメニューの作り方
今回もデモを用意しました。
ご確認ください。
目次
目次
ハンバーガーメニュー
概要
ハンバーガーの構造は下記のようになります。また、上記のアニメーションのように静止したメニューではなく、にゅーっと動いてかっこいいインパクトを与えます。
- aタグの中に空のspanを3つ用意し3本の線にする
- jQueryでclassを制御
- CSSで見た目を調整
- ボタンの次に来る要素を格納する
HTML
1 2 3 4 5 6 7 8 9 |
[sourcecode lang="html"] <p class="btn_hamburger"> <a href="#"> <span></span> <span></span> <span></span> </a> </p> [/sourcecode] |
jQuery
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[sourcecode lang="javascript"] $(function() { var activeClass = 'active'; function hamburgBtn() { $('.btn_hamburger').on('click', function(event) { $button = $(this); event.preventDefault(); $button.find('a').toggleClass(activeClass); $button.next().slideToggle(250); }); }; }); hamburgBtn(); [/sourcecode] |
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 |
[sourcecode lang="css"].btn_hamburger { margin: 0 auto 2em !important; width: 40px; } .btn_hamburger a { position: relative; display: block; height: 30px; -webkit-transition: all .4s; transition: all .4s; box-sizing: border-box; } .btn_hamburger span { position: absolute; display: inline-block; left: 0; width: 100%; height: 2px; background-color: #161b1d; border-radius: 2px; -webkit-transition: all .4s; transition: all .4s; box-sizing: border-box; } .btn_hamburger span:nth-of-type(1) { top: 0; } .btn_hamburger span:nth-of-type(2) { top: 14px; } .btn_hamburger span:nth-of-type(3) { bottom: 0; } .btn_hamburger span:nth-of-type(2)::after { position: absolute; top: 0; left: 0; content: ''; width: 100%; height: 2px; background-color: #161b1d; border-radius: 2px; -webkit-transition: all .4s; transition: all .4s; } .btn_hamburger .active span:nth-of-type(2) { -webkit-transform: rotate(-45deg); -ms-transform: rotate(-45deg); transform: rotate(-45deg); } .btn_hamburger .active span:nth-of-type(2)::after { -webkit-transform: rotate(90deg); -ms-transform: rotate(90deg); transform: rotate(90deg); } .btn_hamburger .active span:nth-of-type(1) { -webkit-transform: translateY(20px) scale(0); -ms-transform: translateY(20px) scale(0); transform: translateY(20px) scale(0); } .btn_hamburger .active span:nth-of-type(3) { -webkit-transform: translateY(-20px) scale(0); -ms-transform: translateY(-20px) scale(0); transform: translateY(-20px) scale(0); } [/sourcecode] |
DEMO 1 : アコーディオンメニュー
概要
- 画面幅が広いときは横並びのレイアウトに、狭いときは縦並びのレイアウトにしてハンバーガーの中へ格納される可変レイアウトにする
- jQueryはclassの切り替えと.slideToggle()の処理程度に留め、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 50 51 52 53 54 55 56 |
[sourcecode lang="html"] <p class="btn_hamburger"> <a href="#"> <span></span> <span></span> <span></span> </a> </p> <section id="demo1" class="section_demo section_demo1"> <ul class="section_demo_list"> <li> <h3 class="trigger"><a href="#">CATEGORY 1</a></h3> <div class="target"> <ul> <li><a href="#">ITEM 1-1</a></li> <li><a href="#">ITEM 1-2</a></li> <li><a href="#">ITEM 1-3</a></li> <li><a href="#">ITEM 1-4</a></li> </ul> </div> </li> <li> <h3 class="trigger"><a href="#">CATEGORY 2</a></h3> <div class="target"> <ul> <li><a href="#">ITEM 2-1</a></li> <li><a href="#">ITEM 2-2</a></li> </ul> </div> </li> <li> <h3 class="trigger"><a href="#">CATEGORY 3</a></h3> <div class="target"> <ul> <li><a href="#">ITEM 3-1</a></li> <li><a href="#">ITEM 3-2</a></li> <li><a href="#">ITEM 3-3</a></li> <li><a href="#">ITEM 3-4</a></li> </ul> </div> </li> <li> <h3 class="trigger"><a href="#">CATEGORY 4</a></h3> <div class="target"> <ul> <li><a href="#">ITEM 4-1</a></li> <li><a href="#">ITEM 4-2</a></li> </ul> </div> </li> </ul> </section> [/sourcecode] |
jQuery
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[sourcecode lang="javascript"] $(function() { function demo1_2(triggerSelector) { // 引数で指定したトリガーをクリックしたとき、クリックしたトリガーの次の要素を展開 $(triggerSelector).on('click', function(event) { $trigger = $(triggerSelector); event.preventDefault(); $(this).toggleClass(activeClass); $(this).next().slideToggle(250); }); }; // 引数でトリガーを指定 demo1_2('#demo1 .trigger'); demo1_2('#demo2 .trigger'); }); [/sourcecode] |
DEMO 2 : 多階層アコーディオンメニュー
概要
何かしらのナビゲーションで7つ以上の選択肢があるととにかく戦慄しますが、多階層のアコーディオンメニューにも対応してみます。
だいたいDEMO01と同様。項目は多くしないこと。
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 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 162 163 164 165 166 167 |
[sourcecode lang="html"] <p class="btn_hamburger"> <a href="#"> <span></span> <span></span> <span></span> </a> </p> <section id="demo2" class="section_demo section_demo2"> <ul class="section_demo_list"> <li> <h3 class="trigger"><a href="#">CATEGORY 1</a></h3> <div class="target"> <ul> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 1</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 1-1</a></li> <li><a href="#">ITEM 1-2</a></li> <li><a href="#">ITEM 1-3</a></li> </ul> </div> </li> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 2</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 2-1</a></li> <li><a href="#">ITEM 2-2</a></li> </ul> </div> </li> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 3</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 3-1</a></li> <li><a href="#">ITEM 3-2</a></li> </ul> </div> </li> </ul> </div> </li> <li> <h3 class="trigger"><a href="#">CATEGORY 2</a></h3> <div class="target"> <ul> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 1</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 1-1</a></li> <li><a href="#">ITEM 1-2</a></li> </ul> </div> </li> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 2</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 2-1</a></li> <li><a href="#">ITEM 2-2</a></li> <li><a href="#">ITEM 2-3</a></li> <li><a href="#">ITEM 2-4</a></li> </ul> </div> </li> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 3</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 3-1</a></li> <li><a href="#">ITEM 3-2</a></li> <li><a href="#">ITEM 3-3</a></li> <li><a href="#">ITEM 3-4</a></li> </ul> </div> </li> </ul> </div> </li> <li> <h3 class="trigger"><a href="#">CATEGORY 3</a></h3> <div class="target"> <ul> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 1</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 1-1</a></li> <li><a href="#">ITEM 1-2</a></li> <li><a href="#">ITEM 1-3</a></li> <li><a href="#">ITEM 1-4</a></li> </ul> </div> </li> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 2</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 2-1</a></li> <li><a href="#">ITEM 2-2</a></li> <li><a href="#">ITEM 2-3</a></li> <li><a href="#">ITEM 2-4</a></li> </ul> </div> </li> </ul> </div> </li> <li> <h3 class="trigger"><a href="#">CATEGORY 4</a></h3> <div class="target"> <ul> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 1</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 1-1</a></li> <li><a href="#">ITEM 1-2</a></li> </ul> </div> </li> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 2</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 2-1</a></li> <li><a href="#">ITEM 2-2</a></li> <li><a href="#">ITEM 2-3</a></li> <li><a href="#">ITEM 2-4</a></li> <li><a href="#">ITEM 2-5</a></li> <li><a href="#">ITEM 2-6</a></li> </ul> </div> </li> </ul> </div> </li> </ul> </section> [/sourcecode] |
jQuery (DEMO 1と同様)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[sourcecode lang="javascript"] $(function() { function demo1_2(triggerSelector) { // 引数で指定したトリガーをクリックしたとき、クリックしたトリガーの次の要素を展開 $(triggerSelector).on('click', function(event) { $trigger = $(triggerSelector); event.preventDefault(); $(this).toggleClass(activeClass); $(this).next().slideToggle(250); }); }; // 引数でトリガーを指定 demo1_2('#demo2 .trigger'); }); [/sourcecode] |
DEMO 3 : コンテンツの格納
概要
アコーディオンって、メニューだけでなくFAQとかコンテンツにもふんふん使われるよねってことでコンテンツも入れてみました。
特にレイアウトは変えず、リキッドな感じに可変です。
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 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 |
[sourcecode lang="html"] <section id="demo2" class="section_demo section_demo2"> <ul class="section_demo_list"> <li> <h3 class="trigger"><a href="#">CATEGORY 1</a></h3> <div class="target"> <ul> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 1</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 1-1</a></li> <li><a href="#">ITEM 1-2</a></li> <li><a href="#">ITEM 1-3</a></li> </ul> </div> </li> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 2</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 2-1</a></li> <li><a href="#">ITEM 2-2</a></li> </ul> </div> </li> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 3</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 3-1</a></li> <li><a href="#">ITEM 3-2</a></li> </ul> </div> </li> </ul> </div> </li> <li> <h3 class="trigger"><a href="#">CATEGORY 2</a></h3> <div class="target"> <ul> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 1</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 1-1</a></li> <li><a href="#">ITEM 1-2</a></li> </ul> </div> </li> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 2</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 2-1</a></li> <li><a href="#">ITEM 2-2</a></li> <li><a href="#">ITEM 2-3</a></li> <li><a href="#">ITEM 2-4</a></li> </ul> </div> </li> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 3</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 3-1</a></li> <li><a href="#">ITEM 3-2</a></li> <li><a href="#">ITEM 3-3</a></li> <li><a href="#">ITEM 3-4</a></li> </ul> </div> </li> </ul> </div> </li> <li> <h3 class="trigger"><a href="#">CATEGORY 3</a></h3> <div class="target"> <ul> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 1</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 1-1</a></li> <li><a href="#">ITEM 1-2</a></li> <li><a href="#">ITEM 1-3</a></li> <li><a href="#">ITEM 1-4</a></li> </ul> </div> </li> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 2</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 2-1</a></li> <li><a href="#">ITEM 2-2</a></li> <li><a href="#">ITEM 2-3</a></li> <li><a href="#">ITEM 2-4</a></li> </ul> </div> </li> </ul> </div> </li> <li> <h3 class="trigger"><a href="#">CATEGORY 4</a></h3> <div class="target"> <ul> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 1</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 1-1</a></li> <li><a href="#">ITEM 1-2</a></li> </ul> </div> </li> <li> <h4 class="trigger"> <a href="#">SUB CATEGORY 2</a> </h4> <div class="target"> <ul> <li><a href="#">ITEM 2-1</a></li> <li><a href="#">ITEM 2-2</a></li> <li><a href="#">ITEM 2-3</a></li> <li><a href="#">ITEM 2-4</a></li> <li><a href="#">ITEM 2-5</a></li> <li><a href="#">ITEM 2-6</a></li> </ul> </div> </li> </ul> </div> </li> </ul> </section> [/sourcecode] |
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 |
[sourcecode lang="javascript"] $(function() { function demo3(triggerSelector) { // 引数で指定したトリガーをクリックしたとき、クリックしたトリガーの次の要素を展開 $(triggerSelector).on('click', function(event) { $trigger = $(triggerSelector); event.preventDefault(); // 他に既に開いている項目がある場合は一度全て閉じる if (!$(this).hasClass(activeClass)) { if ($trigger.hasClass(activeClass)) { $trigger.removeClass(activeClass); $trigger.next().slideUp(250); } } $(this).toggleClass(activeClass); $(this).next().slideToggle(250); }); }; // 引数でトリガーを指定 demo3('#demo3 .trigger'); }); [/sourcecode] |
まとめ
いかがでしょうか。
ワンソースで可変レイアウトってなかなか厳しかったりしますよね。
我々人類が哲学的な気持ちになりつつもいろんな可能性を模索した先で辿り着く答えにはきっと大きな意味があります。
レスポンシブなのにワンソースじゃないーーーーーー闇ですね。
ところで自分のカーソル捌きがなかなか挙動不審で戦慄しました。精進します。