はじめに
スマホ用ページなどでよく利用される、「ハンバーガーメニュー」をCSSのみで実装して見ます。
あくまで機能面の実装を目的としているので、デザイン面でのCSSは省略しています。
基本のHTML構造
<headerclass="header"><h1><ahref="index.html">TITLE</a></h1><divclass="menu-trigger">開く
</div><navid="top-nav"class="nav-menu"><ul><li><ahref="index.html">HOME</a></li><li><ahref="about.html">ABOUT</a></li><li><ahref="contact.html">CONTACT</a></li></ul></nav></header>ハンバーガーメニューの実装イメージ
「開く」ボタンと「閉じる」ボタンを押すことでメニューの開閉をする簡単な構造になります。
titleとmenuを両端に配置
.header{display:flex;justify-content:space-between;}flexboxを使って、左右両端に配置します。
nav-menuを右上に固定
.header{position:relative;}.nav-menu{position:absolute;top:0;right:0;}position:absoluteを使って位置を固定しています。
その際、基準となるheaderにposition: relativeを設定します。
メニュー開閉の仕組みを作る
メニュー開閉の仕組みは、cssのtarget属性にて実装します。
<headerclass="header"><h1><ahref="index.html">TITLE</a></h1><divclass="menu-trigger"><ahref="#top-nav">開く</a></div><navid="top-nav"class="nav-menu"><ahref="#!"class="menu-close">閉じる</a><ul><li><ahref="index.html">HOME</a></li><li><ahref="about.html">ABOUT</a></li><li><ahref="contact.html">CONTACT</a></li></ul></nav></header>aタブを用いて、対象のid属性を指定しています。
閉じるボタンの href="#!" は、ターゲットを外す目的で指定しています。
.nav-menu:not(:target){}.nav-menu:target{}非表示のスタイルを :not(:target)
表示スタイルを :target に記述します。
nav-menuを非表示にする
.nav-menu:not(:target){opacity:0;visibility:hidden;}opacityで透明度を0に、visibility: hiddenで非表示にしています。
メニュー表示時、nav-menuを表示させる
.nav-menu:target{opacity:1;visibility:visible;}opacityで透明度を1に、visibility: visibleで表示しています。
開閉時のフェードイン・アウト
.nav-menu:not(:target){transition:1s;}.nav-menu:target{transition:1s;}transitionでプロパティ変化の時間を指定しています。
閉じるボタンを右上に固定する
.menu-close{position:absolute;top:0;right:0;}position:absoluteを使って位置を固定しています。
各要素の重なり具合を調整する
下から
- header(body)
- menu-trigger
- nav-menu
の順番で重なるようにz-indexを指定していきます
.menu-trigger{position:relative;z-index:2;}.nav-menu{z-index:3;background:white;}z-indexは、positionプロパティが設定されていないと適応されないため、position: relativeを追記しています。
nav-menuは、menu-triggerを隠すため、背景色をつけています。
ここまでのまとめ
<headerclass="header"><h1><ahref="index.html">TITLE</a></h1><divclass="menu-trigger"><ahref="#top-nav">開く</a></div><navid="top-nav"class="nav-menu"><ahref="#!"class="menu-close">閉じる</a><ul><li><ahref="index.html">HOME</a></li><li><ahref="about.html">ABOUT</a></li><li><ahref="contact.html">CONTACT</a></li></ul></nav></header>.header{display:flex;justify-content:space-between;position:relative;}.nav-menu{position:absolute;top:0;right:0;z-index:3;background:white;}.nav-menu:not(:target){opacity:0;visibility:hidden;transition:1s;}.nav-menu:target{opacity:1;visibility:visible;transition:1s;}.menu-close{position:absolute;top:0;right:0;}.menu-trigger{position:relative;z-index:2;}レスポンシブ対応
PC版とスマホ版でCSSを切り替えます。
<head><metaname="viewport"content="width=device-width, initial-scale=1"></headcssにてメディアクエリを使用するため、headタグにてviewportを読み込みます。
PC版のスタイルは
.header{display:flex;justify-content:space-between;position:relative;}.nav-menu{display:block;}.nav-menuul{display:flex;justify-content:space-between;}.nav-menuli{padding-left:10px;}.menu-close{display:none;}.menu-trigger{display:none;}で作られているものとして話を進めます。
メディアクエリの実装
PCとスマホのCSSで異なる点を記述してみます。
--共通--.header{display:flex;justify-content:space-between;position:relative;}.nav-menu{--PC--display:block;--スマホ--position:absolute;top:0;right:0;z-index:3;background:white;}--PC--.nav-menuul{display:flex;justify-content:space-between;}.nav-menuli{padding-left:10px;}--スマホ--.nav-menu:not(:target){opacity:0;visibility:hidden;transition:1s;}.nav-menu:target{opacity:1;visibility:visible;transition:1s;}.menu-close{--PC--display:none;--スマホ--position:absolute;top:0;right:0;}.menu-trigger{--PC--display:none;--スマホ--position:relative;z-index:2;}今回はスマホ版をデフォルトとし、PC版をメディアクエリで変更していきます。
.header{display:flex;justify-content:space-between;position:relative;}.nav-menu{position:absolute;top:0;right:0;z-index:3;background:white;}@mediascreenand(min-width:1000px){.nav-menu{display:block;}}@mediascreenand(min-width:1000px){.nav-menuul{display:flex;justify-content:space-between;}}@mediascreenand(min-width:1000px){.nav-menuli{padding-left:10px;}}@mediascreenand(max-width:1000px){.nav-menu:not(:target){opacity:0;visibility:hidden;transition:1s;}}@mediascreenand(max-width:1000px){.nav-menu:target{opacity:1;visibility:visible;transition:1s;}}.menu-close{position:absolute;top:0;right:0;}@mediascreenand(min-width:1000px){.menu-close{display:none;}}.menu-trigger{position:relative;z-index:2;}@mediascreenand(min-width:1000px){.menu-trigger{display:none;}}pc版のスタイルに対して、@media screen and (min-width: 1000px)にてCSSを変更しています。
.nav-menu:not(:target), .nav-menu:target に関してはスマホ版のみのスタイルなので、@media screen and (max-width: 1000px) にて指定してあります。
以上にてレスポンシブ対応が完了しました。
ブレークポイントを増やす場合は、適宜追加してください。
