スマートデバイス向けCSSナビゲーションメニュー実装解説
スマートフォン向けナビゲーションメニューなサンプルを3つ用意してそれぞれで実装解説したいと思います。実装に入る前に少し注意というかコツみたいなお話をしておきます。それは必要なボックス要素のtopを<body>に対して取り敢えず0に揃えるということです。必要なbox要素に<body>に対してcssでposition: absolute;、position: fix;、top: 0;などを指定することでbody上部に固定してあげます。どんなことでもそうだと思いますが、一度0や白紙にしてやることで全体が見えやすくなると思います。
それではcssナビゲーションメニューを3種類用意してそれぞれで実装例を示して解説していきたいと思います。
スマートデバイス向けCSSナビゲーションメニュー#01実装例
上のモバイルデバイス向けCSSナビゲーションメニュー実装例のソースをHTML、JavaScript、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 |
<!DOCTYPE html> <html> <head> <title>スマートデバイス向けCSSメニュー#01</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script> <link href="menu.css" rel="stylesheet" type="text/css"/> <script src="menu.js" type="text/javascript"></script> </head> <body> <div id="wrap" class="wrap1"> <header> <img src="image/nike_logo.png" alt=""/> <div class="nav-icon"> <button> <span></span> </button> </div> </header> <article> <nav> <ul> <li>home</li> <li>about</li> <li>service</li> <li>contact</li> </ul> </nav> <section class="s1"> <p>just do it !</p> </section> <section class="s2"> <p>aaaaaaaaaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaaaaaaaaa</p> </section> </article> </div> </body> </html> |
ナビゲーションメニュー#01 HTML実装解説
今回実装した3種類のナビゲーションメニューのhtmlで共通に必要なことは、<article>タグの中に<nav>タグが含まれるか、含まれないかです。正直<nav>タグがどこに配置してあっても実装することはできます。実際<footer>タグの下に記述している例などもありますのでそこはそれぞれの個性や考え方で少し変わってきます。
JavaScript(JQuery)共通
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$(document).ready(function () { $(".nav-icon button").click(function () { $(".nav-icon").toggleClass("open"); $("nav").toggleClass("open"); }); $(".nav-icon2 button").click(function () { $(".nav-icon2").toggleClass("open"); $("nav").toggleClass("open"); $("#wrap").toggleClass("open"); }); $(".nav-icon3 button").click(function () { $(".nav-icon3").toggleClass("open"); $("nav").toggleClass("open"); $("#wrap").toggleClass("open"); }); }); |
ナビゲーションメニュー JavaScript(JQury)実装解説
ナビゲーションメニューもメニューアイコンと同じようにJQuryで必要なところにopenクラスをつけ外しします。アニメーション切り替え用のトグルスイッチです。
ナビゲーションメニュー3種類とも共通ですので以下割愛させて頂きます。
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 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
/** menu#01 **/ #wrap{ width: 290px; position: relative; margin: 0 auto; height: 100%; } #wrap button{ height: 100%; background: transparent; border: none; outline: none; } header{ width: 100%; text-align: center; position: relative; background: #fff; } #wrap.wrap1 header{ z-index: 100; } header img{ width: 11.5%; height: auto; padding: .5em 0; } #wrap.wrap1 .nav-icon{ position: absolute; top: 0; right:2.5%; height: 100%; } article{ position: absolute; top: 0; width: 100%; height: 100vh; background: #f7f7f7; } #wrap.wrap1 article{ z-index: 10; } #wrap.wrap1 nav{ background:#ccc; width: 100%; text-align: center; margin-top: -55%; opacity: 0; transition: all 1000ms ease 300ms; padding: 50px 0 0; } #wrap.wrap1 nav.open { margin-top: 0; opacity: 1; transition: all 1000ms ease 300ms; } ul{ padding: 2em .5em; } li{ list-style: none; } section{ text-align: center; } section.s1{ padding: 2.5em 0; } section:nth-child(2){ background:#66ffcc; font-size: 1.25em; } section:nth-child(3){ background:#f7f7f7; padding: 1em 0 2em; } *{ padding: 0; margin: 0; } body{ height: 100vh; } /** icon01 **/ #menu{ display: flex; justify-content: space-around; } .nav-icon{ overflow: hidden; } .nav-icon button{ overflow: hidden; height: 3.5em; padding: 1em .5em; } .nav-icon button span{ transition: background 500ms ease 500ms; position: relative; display: block; width: 2em; height: .1em; background: #333; } .nav-icon button span:after{ transition: top 500ms ease 500ms,transform 250ms cubic-bezier(.55,.055,.675,.19); display: block; position: absolute; content: ""; top: -1em; width: 2em; height: .1em; background: #333; } .nav-icon button span:before{ transition: top 500ms ease 500ms,transform 250ms cubic-bezier(.55,.055,.675,.19); display: block; position: absolute; content: ""; top: 1em; width: 2em; height: .1em; background: #333; } .nav-icon.open button span{ transition: background 40ms ease 500ms; background: transparent; } .nav-icon.open button span:after{ transition: top 500ms ease, transform 200ms cubic-bezier(.55,.055,.675,.19) 500ms; top: 0; transform: rotate(-45deg); } .nav-icon.open button span:before{ transition: top 500ms ease, transform 200ms cubic-bezier(.55,.055,.675,.19) 500ms; top: 0; transform: rotate(45deg); } |
ナビゲーションメニュー#01 CSS実装解説
ナビゲーションが縦に移動するだけの実装です。<article>タグの中に<nav>タグが含まれるので冒頭のところで少し述べたように<article>タグにcssでpostion:absolute; top:0;を指定してbodyのtopに固定します。
headerとarticleにcssのz-indexプロパティーでそれぞれ100と10を指定します。positionプロパティーを指定したbox要素には深さの階層(z軸)がありz-indexはその深さの階層を指定するものです。値が大きい方が階層の重なりは上にいきます。
positionプロパティーを指定したbox要素では通常htmlファイルの中で下に記述されている順で深さの階層は上になります。<div>タグが5つならんでいてすべてにpositionプロパティーを指定すると一番下の<div>タグが一番上の階層に重なります。z-indexプロパティーは値を指定することで重なりの順を変えることができます。
冒頭のほうで少し述べさせていただいたナビゲーションメニューの実装で<nav>タグを<footer>タグの下に持ってくるのは一番下の深度の階層は一番上なので、cssでのz-indexプロパティーの指定を回避することができるからです。
深度の階層やcssのz-indexプロパティーの知識があれば皆さんが実装し易い方法で実装して構わないと思います。多分どこでも実装できると思います。
次はナビゲーションメニューの<nav>タグにcssのmarginプロパティーのトップに‐55%を指定してナビゲーションが見えなくなるまでコンテンツを上に引き上げます。この設定は海外のサイトなどで確認するとブラウザによって異なるようです。chromeでは-50%、その他のブラウザでは-100%を指定してくださいとなっていますのでそれぞれのブラウザでまずは-50%、-100%を指定してそこから微調整して頂ければと思います。
ナビゲーションメニューのデフォルトの設定はこれで終わりになります。あとはcssナビゲーションアイコンと同様にopenクラスが有るか無いかでcssのtrsitionプロパティーを使用してmarginのトップの位置を‐55%と0でアニメーションさせて完成です。実行時時間に1000msを指定してあります。
スマートデバイス向けCSSナビゲーションメニュー#02実装例
二つ目のナビゲーションメニューはナビゲーションがコンテンツに重なる実装です。割とスタンダードに使われているナビゲーションメニューです。分かり易いようにナビゲーションを少し透明にしていますが実際ははずして構いません。実装例のソースをHTML、Cssそれぞれを示して解説していきたいと思います。JavaScriptは前回と共通です。
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 |
<!DOCTYPE html> <html> <head> <title>スマートデバイス向けCSSメニュー2</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script> <link href="menu.css" rel="stylesheet" type="text/css"/> <script src="menu.js" type="text/javascript"></script> </head> <body> <div id="wrap" class="wrap2"> <header> <img src="image/nike_logo.png" alt=""/> <div class="nav-icon2"> <button> <span></span> </button> </div> </header> <article> <nav> <ul> <li>home</li> <li>about</li> <li>service</li> <li>contact</li> </ul> </nav> <section class="s1"> <p>just do it !</p> </section> <section class="s2"> <p>aaaaaaaaaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaaaaaaaaa</p> </section> </article> </div> </div> </body> </html> |
ナビゲーションメニュー#02 HTML実装解説
前回とかわりません。<nav>タグも<article>タグの中に含まれています。<nav>タグを<article>タグの外に出して実装することもできますが、今回は中に入れたまま実装してみたいと思います。
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 |
/** menu2 **/ #wrap.wrap2 header{ width: 100%; text-align: center; position: relative; background: #fff; z-index: 1000; } #wrap.wrap2 header img{ width: 11.5%; height: auto; padding: .5em 0; } #wrap.wrap2 .nav-icon2{ position: absolute; top: 0; right:2.5%; height: 100%; z-index: 1500; } #wrap.wrap2 .nav-icon2 button{ height: 100%; background: transparent; border: none; outline: none; } #wrap.wrap2 article{ width: 100%; background: #f7f7f7; } #wrap.wrap2 nav{ width: 100%; background: #ccc; text-align: center; position: absolute; top: 0; height: 100vh; opacity: 0; transform: translateY(-100%); transition: all 1000ms ease 300ms; } #wrap.wrap2 nav.open { opacity: .8; transform: translateY(0%); transition: all 1000ms ease 300ms; } #wrap.wrap2 ul{ padding: 5em .5em 2em; } #wrap.wrap2 section:nth-child(2){ background:#990000; font-size: 1.25em; color: #ffff00; padding: 2.5em 0; text-align: center; } #wrap.wrap2 section:nth-child(3){ background:#f7f7f7; padding: 1em 0 2em; font-size: 1em; } *{ padding: 0; margin: 0; } body{ height: 100vh; } /** nav-icon2 **/ .nav-icon2{ overflow: hidden; } .nav-icon2 button{ overflow: hidden; height: 3.5em; padding: 1em .5em; } .nav-icon2 button span:before{ transition: all 1000ms ease 1000ms; display: block; position: absolute; content: ""; width: 2em; height: .1em; background: #333; top: 1em; } .nav-icon2 button span{ transition: top 1000ms ease; position: relative; display: block; width: 2em; height: .1em; background: #333; top: -1em; } .nav-icon2 button span:after{ transition: top 1000ms ease; display: block; position: absolute; content: ""; width: 2em; height: .1em; background: #333; top: 2em; } .nav-icon2.open button span:before{ transition: all 1000ms ease; margin:0 0 0 2em; opacity: 0 } .nav-icon2.open button span{ transition: top 1000ms ease 1000ms; top:0; } .nav-icon2.open button span:after{ transition: top 1000ms ease 1000ms; top:0; } |
ナビゲーションメニュー#02 CSS実装解説
ナビゲーションメニュー#01では<article>タグに設定していたposition: absolute;とtop: 0;をナビゲーションメニュー#02では<nav>タグに付け替えて<article>タグのpositionプロパティーとtopプロパティーを外します。外さずに実装することもできますが今回は前回との比較もあるのではずしておきます。
<article>タグのトップに<nav>タグのトップを合わせることもできますが、<body>のトップに合わせた方が高さの計算が楽になります。高さをデバイスの高さに合わせたい時、<body>のトップに合わせたbox要素の高さはすべて100%か100vhで指定できます。
positionプロパティーを設定した<header>と<nav>タグにそれぞれz-indexプロパティーで100、10を指定します。
transformプロパティーでtranslateY(-100%)を指定します。
trasitionプロパティーでtranslateY(-100%)、translateY(0)でナビゲーションをアニメーションさせて完成です。実行時間は1000msに設定してあります。
スマートデバイス向けCSSナビゲーションメニュー#03実装例
今度は横に移動するスマートデバイス向けCSSナビゲーションメニューです。横移動のナビゲーションメニュー、縦移動のナビゲーションメニューとともにCSSナビゲーションメニューの実装でスタンダードなものを二つ組み合わせて実装してみました。
実装例のソースをHTML、CSSそれぞれを示して解説していきたいと思います。JavaScriptは共通なので割愛します。
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 |
<!DOCTYPE html> <html> <head> <title>スマートデバイス向けCSSメニュー3</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script> <link href="menu.css" rel="stylesheet" type="text/css"/> <script src="menu.js" type="text/javascript"></script> </head> <body> <div id="wrap" class="wrap3"> <header> <img src="image/nike_logo2.png" alt=""/> <div class="nav-icon3"> <button> <span></span> </button> </div> </header> <nav> <ul> <li>home</li> <li>about</li> <li>service</li> <li>contact</li> </ul> </nav> <article> <section class="s1"> <p>just do it !</p> </section> <section class="s2"> <p>aaaaaaaaaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaaaaaaaaa</p> </section> </article> </div> </body> </html> |
ナビゲーションメニュー#03 HTML実装解説
今回のナビゲーションメニューは<nav>タグを<article>タグの外に出して実装しています。<article>要素にに横に移動するアニメーションを実装するため<nav>タグを内部に残しておくと、<nav>要素も横に移動してしまうためです。
<nav>タグを内部に残しておいてもナビゲーションメニューは実装できますが、シンプルに分かり易くするため今回は外にだして実装してみました。
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 162 163 164 165 166 167 |
/** menu3 **/ .wrap3 header{ background: #e21515; z-index: 100; } .wrap3 header img{ width: 12.5%; height: auto; padding: .35em 0; } .wrap3 .nav-icon3{ position: absolute; top: 0; right:2.5%; height: 100%; z-index: 100; } .wrap3 nav{ background:#ccc; width: 100%; text-align: center; position: absolute; top: 0; height: 100vh; height: calc(100vh - 3em); opacity: 0; transform: translateY(-100%); transition: all 1000ms ease 300ms; padding: 3em 0 0; } .wrap3 nav.open { opacity: 1; transform: translateY(0); transition: all 1000ms ease 300ms; } li{ list-style: none; } .wrap3 article { height: calc(100vh - 55px); } .wrap3 article{ -webkit-transform:translateY(0%); -moz-transform:translateY(0%); transform:translateY(0%); transition: all 1000ms ease 300ms; } .wrap3.open article{ -webkit-transform:translateX(-200%); -moz-transform:translateX(-200%); transform:translateX(-100%); transition: all 1000ms ease 300ms; } section{ text-align: center; } .wrap3 section:nth-child(1){ background: no-repeat url("image/crack.jpg"); background-size: 105% auto; padding: 15% 0; font-size: 1.25em; color: #ff3300; } .wrap3 section:nth-child(2){ background:#f7f7f7; padding: 1em 0 2em; font-size: 1em; } /** nav-icon3 **/ .nav-icon3{ overflow: hidden; } .nav-icon3 button{ overflow: hidden; height: 3.5em; padding: 1em .5em; } .nav-icon3 button span:before{ transition: all 1000ms ease 1300ms; display: block; position: absolute; content: ""; width: 2em; height: .1em; background: #333; top: 1em; } .nav-icon3 button span{ transition: top 1000ms ease 500ms,transform 300ms cubic-bezier(.55,.055,.675,.19); position: relative; display: block; width: 2em; height: .1em; background: #333; top: -1em; } .nav-icon3 button span:after{ transition: top 1000ms ease 500ms,transform 300ms cubic-bezier(.55,.055,.675,.19); display: block; position: absolute; content: ""; width: 2em; height: .1em; background: #333; top: 2em; } .nav-icon3.open button span:before{ transition: all 1000ms ease; margin:0 0 0 2em; opacity: 0 } .nav-icon3.open button span{ transition: top 1000ms ease 1000ms,transform 250ms cubic-bezier(.55,.055,.675,.19) 2000ms; top:0; transform: rotate(-45deg); } .nav-icon3.open button span:after{ transition: top 1000ms ease 1000ms,transform 250ms cubic-bezier(.55,.055,.675,.19) 2000ms; top:0; transform: rotate(90deg); } *{ padding: 0; margin: 0; } body{ height: 100vh; } |
ナビゲーションメニュー#03 CSS実装解説
最後のナビゲーションメニューの解説に入ります。まず<header>要素にposition: relative、z-index:100;、<nav>要素にposition: absolute;、top: 0;をcssで指定します。それぞれの重なりを確認しながら、うまくいかなければpositionプロパティーやz-indexプロパティーを重なりの順を考えながら、必要な要素に指定して下さい。
ナビゲーションメニューの<nav>要素にtransform: translateY(-100%);を設定して<nav>要素のbottomを<body>要素のtopの位置まで引き上げます。これでデフォルトの設定は終わりです。
ナビゲーションメニューアイコンをクリックし、openクラスが付加された状態で<nav>要素にtransform: translateY(0%);、<article>要素にtransform: translateX(-100%);を指定します。
ナビゲーションメニューの<nav>要素と<article>要素にtranslateプロパティーでアニメーションの実行時間とディレイタイムを設定して終了です。
モバイルデバイス向けCSSナビゲーションメニューとCSSナビゲーションメニューアイコンの実装解説まとめ
モバイルデバイス向けCSSナビゲーションメニューとCSSナビゲーションメニューアイコンの実装解説を何種類か例をあげながら記事にしてみましたが、いかがだったでしょうか?
ウェブの閲覧媒体がスマートフォンに移行した現在、モバイルデバイス向けCSSナビゲーションメニューとCSSナビゲーションメニューアイコンを含むスマートデバイスに向けたUIの実装は制作側としては完全に必須の技術です。
今回の記事がホームページ制作に関わるすべの方の一助になれば幸いに思います。それではまた。