【HTML/CSS】ハンバーガーメニューPart.2「CSSのみでシンプル実装コード編」
当ブログのGoogleアナリティクスによると、検索キーワードに「ハンバーガーメニュー」が多いようです。2020年現在のスマホ表示、レスポンシブ対応には必須なので検索される方がかなり多いようですね。
Part1でハンバーガーメニューの「必要?不要?論」を書いてから少し間が開きましたが、今回やっと実装コードを紹介するということでPart2を書いていきたいと思います。
以前までの流れ、ハンバーガーメニュー「必要?不要?論」や代替方法など気になる方は以下記事ご参照ください。
ハンバーガーメニュー実装コード例
例として当ブログのメニューを少しシンプルにした場合のコードを挙げます。
実際にはアイコンにSVGを用いてたりメニュー項目が違ったりしますがコードが長くなるので省略して、以下のような感じにしています。
ではコードの内容について少し解説したいと思います。
HTML
<div id="top-editarea"> <!-- メニュー表示切り替え用チェックボックス --> <input type="checkbox" id="main-nav" class="d-none"> <!-- スマホ用ハンバーガーメニューアイコン --> <div class="d-none sp-block nav-icon-wrap"> <label for="main-nav" class="nav-icon"></label> </div> <!-- メニュー --> <nav class="header-nav-wrap"> <ul class="d-flex list-unstyled header-nav"> <li><a href="https://webabc.hatenablog.jp/archive/category/HTML%2FCSS">HTML&CSS</a></li> <li><a href="https://webabc.hatenablog.jp/archive/category/JavaScript">JavaScript</a></li> <li><a href="https://webabc.hatenablog.jp/archive/category/Wordpress">Wordpress</a></li> <li><a href="https://webabc.hatenablog.jp/archive/category/Laravel">Laravel</a></li> </ul> </nav> </div>
一番外の<div id="top-editarea">は、はてなブログで自動で入るコードです。
はてなブログの「デザイン設定>ヘッダ>タイトル下」という箇所にそれ以下のコードを記述しています。
その後はまず、input type="checkbox"でチェックボックスを非表示のclass="d-none"をつけて記述しています。この部分は一切表示されません。
そして、次の<label for="main-nav" class="nav-icon"></label>の部分のfor="main-nav"で先ほどのチェックボックスと紐づけています。
この部分でハンバーガーメニューのアイコンを表示しているので、アイコンをクリックしたら紐づいているチェックボックスのチェック状態が切り替わるという具合です。
CSS
*{ margin: 0;padding: 0; box-sizing: border-box; } .list-unstyled{ list-style: none; } .d-none{ display: none; } .d-flex{ display: flex; justify-content: space-evenly; } #top-editarea{ overflow: hidden; } .header-nav{ background: #47a89c; padding: 1em; } .header-nav a{ color: #fff; } @media screen and (max-width: 480px){ .sp-none{ display: none; } .sp-block{ display: block; } .nav-icon-wrap{ position: absolute; top: 0; right: 0; z-index: 999; background: white; box-shadow: 0 0 1px #333; } .nav-icon{ position: relative; display: block; width: 1.7em; height: 1.7em; } .nav-icon::before, .nav-icon::after{ content: ""; display: block; width: 60%; border-top: 1px solid #555; position: absolute; top: 30%; left: 20%; transition: .3s all; } .nav-icon::after{ top: 70%; } .header-nav-wrap{ display: block; position: relative; top: 0; left: 100%; transition: all .4s; width: 100%; z-index: 990; } .header-nav{ margin: 0; } #main-nav:checked ~ nav{ display: block; left: 0; } #main-nav:checked ~ .nav-icon-wrap>.nav-icon::before{ top: 50%; transform: rotate(45deg); } #main-nav:checked ~ .nav-icon-wrap>.nav-icon::after{ top: 50%; transform: rotate(-45deg); } .header-nav{ flex-direction: column; background: #47a89c; padding: 1em; } .header-nav a{ color: #fff; } }
CSSではまず簡易のリセットCSSや.d-flexなどのbootstrap的な基本のクラスを定義しつつPCファーストでPC用の記述をしています。
大事なのは@media screen and (max-width: 480px){ 以降のスマホ用の記述ですね。
特に、#main-nav:checked ~ navで、チェックボックスがオンだった場合のセレクタとしている部分に注目です。
「:checked 」でチェックボックスがオンの状態、「~」を使うことで、「その要素以降の同じ階層のセレクタの指定」という意味になります。
必ずしもここで「~」セレクタを用いる必要があるというわけではありませんが、是非覚えておくとよいと思います。
このセレクタによって、ハンバーガーアイコンがクリックされた時にチェックボックスがオンになり、ナビゲーションが表示されるというような動作になっています。
ハンバーガーメニューのアイコンアニメーション
今回なるべくシンプルに記述のためハンバーガーメニューのアイコンは2本線のボーダーのアニメーションにしました。
.nav-iconのbeforeとafterの擬似要素でそれぞれボーダーを指定してposition: absolute;で、ひとつはtop: 30%;に、もうひとつはtop: 70%;に配置しています。
そしてアニメーション用にtransition: all .4s;を指定。「.4s」は0.4秒かけてアニメーションするという意味で、0は省略しています。
あとは先ほどのメニューの表示と同じく、チェックボックスがオンになった時に#main-nav:checked ~ .nav-icon-wrap>.nav-icon::before{ と指定して、transform: rotate(45deg)で回転角度をつけています。もう片方::afterでは逆向きの角度でrotate(-45deg)とします。
位置はどちらもtop: 50%にするとちょうど真ん中で×が描けるようになりますね。
3本線のボーダーの場合はbefore/afterの擬似要素ではなく普通に<span>を3つ配置するとよいかと思います。その際にはクリック後に1本は消してあげて「×」を描きます。
CSSだけでハンバーガーメニューは簡単
チェックボックスとラベルの連携やCSSのセレクタを駆使するので慣れていないと少し難しく感じるかもしれませんが、理解すると案外シンプルに実装できるかと思います。
JavaScriptやjQueryに慣れていればそちらの方が簡単かもしれませんが、はてなブログへの実装などの場合はJSを記述するのはひと手間かかったりするのでCSSだけで実装できると助かります。
まずは今回のようなCSSのみでのシンプルな実装から導入していただければと思います。
最後までお読みいただいてありがとうございました。
お役に立てたなら幸いです。
webabc.hatenablog.jpwebabc.hatenablog.jpwebabc.hatenablog.jp