前回作った三本線のボタンに、右からスライドして出てくるメニューを組み合わせます。このレッスンで、CSSだけのハンバーガーメニューが完成します。

手順1:メニューのHTMLを足す
label の後ろに、メニュー(nav)を足します。input → label → nav の順番に並べるのがポイントです。
<header class="header">
<a class="logo" href="#">Sample Cafe</a>
<input type="checkbox" id="menu-btn">
<label for="menu-btn" class="menu-toggle">
<span></span>
<span></span>
<span></span>
</label>
<nav class="global-nav">
<ul>
<li><a href="#">HOME</a></li>
<li><a href="#">コンセプト</a></li>
<li><a href="#">メニュー</a></li>
<li><a href="#">店舗案内</a></li>
<li><a href="#">お問い合わせ</a></li>
</ul>
</nav>
</header>
手順2:メニューを画面の外に隠しておく
メニューは、ふだんは画面の右の外側に置いておきます。position: fixed で画面に固定し、right: -100% で画面の幅ぶん右へ押し出します。
/* ---- メニュー本体:最初は画面の右外に隠しておく ---- */
.global-nav {
position: fixed;
top: 0;
right: -100%; /* 画面の外(右側)へ押し出す */
width: 80%;
max-width: 360px;
height: 100vh;
padding: 90px 30px 30px;
background: #3b2a20;
color: #fff;
transition: right .4s; /* 0.4秒かけてスライド */
z-index: 10;
}
.global-nav a {
display: block;
padding: 14px 0;
border-bottom: 1px solid rgba(255,255,255,.2);
}
height: 100vh は「画面の高さいっぱい」という意味です。vh は画面の高さを100等分した単位でしたね。
手順3:チェックが入ったら、メニューを画面の中へ
前回と同じく :checked ~ を使います。チェックが入ったら right を 0 にすると、メニューが画面の右端にぴったり収まります。transition を書いておいたので、0.4秒かけてスライドして出てきます。
/* ---- チェックが入ったらメニューを画面の中へ ---- */
#menu-btn:checked ~ .global-nav {
right: 0;
}
手順4:ボタンをメニューより手前に出す
このままだと、出てきたメニューがボタンの上に重なって、ボタンが押せなくなります。ボタンに position: relative と z-index を付けて、メニューより手前に出します。メニューの背景が濃い色なので、開いたときは線を白にします。
/* ボタンはメニューより手前に。開いたら線を白に */
.menu-toggle {
position: relative;
z-index: 20;
}
#menu-btn:checked ~ .menu-toggle span {
background: #fff;
}
z-index は重なりの順番で、数字が大きいほど手前に表示されます。メニューが10、ボタンが20なので、ボタンが手前です。くわしくはz-indexのレッスンで学びます。
「+」と「~」の違い
兄弟要素を指定する記号は2つあります。よく似ているので、ここで整理しておきましょう。
| 記号 | 名前 | 指定できる要素 |
|---|---|---|
A + B | 隣接兄弟結合子 | Aのすぐ後ろにある兄弟のBだけ |
A ~ B | 一般兄弟結合子 | Aより後ろにある兄弟のBすべて |
今回のHTMLは input → label → nav の順です。nav は input のすぐ後ろではないので、+ では届きません。だから ~ を使っています。
ほかの隠し方:display と animation
メニューを隠す方法は、画面の外へ押し出すだけではありません。display: none で消しておき、チェックが入ったら display: block にする方法もあります。この方法だと transition が効かないので、ふわっと出したいときは animation を使います。
nav {
display: none; /* ふだんは消しておく */
}
#menu-btn:checked ~ nav {
display: block; /* チェックが入ったら表示 */
animation: fadeIn 1s; /* 1秒かけてふわっと */
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
CSSだけの方法の弱点
CSSだけでもメニューは動きますが、実際のサイトで使うには弱点もあります。
- チェックボックスは本来、フォームの部品です。読み上げソフトを使う人に「メニューのボタン」だと伝わりにくくなります。
- キーボードの Tab キーで、ボタンに移動できません。
- メニューの中のリンク(同じページ内へのリンク)を押しても、メニューが開いたままになります。
そこで次のレッスンでは、同じメニューをJavaScriptで動かします。しくみはほとんど同じなので、ここまでが理解できていれば大丈夫です。
まとめ
- メニューは
position: fixedとright: -100%で画面の外に隠しておく :checked ~ .global-navでright: 0にすると、画面の中へスライドして出てくる- ボタンは
z-indexでメニューより手前に出す +はすぐ後ろの兄弟だけ、~は後ろの兄弟すべて