ドロワーメニュー

ページの隅っこにあるやのアイコンをタップするとメニューがスライドしてくるの、よく見かけますね。引き出しみたいに出し入れできるメニューだからドロワーメニューとかって言います。ここではそんなドロワーメニューをCSSで作ってみます。
開閉する仕組み
メニューが開閉する仕組みは、これまでのサンプル同様<input>と<label>を使った方法で、今回はラジオボタンじゃなくて、チェックボックスを使います:)。
ページ全体のHTMLの構造は以下の通り。
<body>
<input type="checkbox" id="drawer">
<label for="drawer" class="open"></label>
<label for="drawer" class="close"></label>
<nav class="menu">
⋮
</nav>
<div class="contents">
<header>
⋮
</header>
<article>
⋮
</article>
<footer>
⋮
</footer>
</div>
</body>メニューを開閉するためのボタンとなるlabel要素は2つ用意しておき、ひとつは開く・閉じるの両用、もうひとつを閉じる用としておきます。
両用の<label for="drawer" class="open">は、常に見えているボタンの形をしたもの。閉じる用の<label for="drawer" class="close">は、全面を覆うように固定配置しておきます。
そして、スイッチの役割となるチェックボックスは、ページの先頭に設置。
これが:checkedになった時に、それ以降の兄弟要素<label>と<nav>のスタイルを変える仕組みです。
全面を覆っている閉じるボタンは、メニューが閉じている時はpointer-events: noneでポインターでの操作を無効にしておき、メニューが開いた時にはautoにして、クリックできるようにします。スライドショーの矢印ボタンの時と同じ方法ですね;)。
.close {
z-index: 1;
inset: 0;
pointer-events: none;
transition: background-color .6s;
}
#drawer:checked ~ .close {
pointer-events: auto;
background-color: rgba(0,0,0,.3);
}pointer-events: noneでポインターイベントが無効になるので、前面を覆っていても、その下のコンテンツには触ることができるってわけ:D。
ドロワーメニューが開いたらスクロールをロックする
ドロワーメニューが開いている時には、下のコンテンツのスクロールを止めたいって時もあるでしょう。そんな時には、以下のように、ページ全体をひとつのdiv要素で括って、その要素内でスクロールするようにします。
<body>
<div class="container">
<input type="checkbox" id="drawer">
<label for="drawer" class="open"></label>
<label for="drawer" class="close"></label>
<nav class="menu">
⋮
</nav>
<div class="contents">
⋮
</div>
</div>
</body>body要素の内側のdiv要素.containerに、以下のようにスタイルを指定すれば、html要素ではスクロールしなくなり、.container内でスクロールするようになります。
.container {
position: absolute;
inset: 0;
overflow: auto;
}そうすると、ドロワーメニューが開いた時に、閉じるボタン用のlabel要素がページ全体を覆っている故、下のコンテンツに触れなくなって、スクロールもできなくなります:o。
ウィンドウの幅に合わせてメニューを使い分ける
ドロワーメニューは、画面が狭い時だけ使えればよくて、画面が広い時にはコンテンツ内にメニューを表示させときたいって時もあるでしょう。
そんな時はMedia Queriesという構文を使います。メディアクエリとは、メディアの特性に合わせてスタイルを出し分けるための方法。詳しくは後述。
例えば、以下のように指定すれば、画面の横幅が520px以上の時にはドロワーメニューのアイコンが非表示になり、画面の横幅が519px以下の時にはコンテンツ内のメニューが非表示になります。
@media (min-width: 520px) {
.open {
display: none;
}
}
@media (max-width: 519px) {
header nav {
display: none;
}
}上のサンプルでは、メディアクエリを使って、ブラウザの横幅に合わせて、普通なメニューを表示するスタイルと、ドロワーメニューを表示するスタイルを出し分けてるということになります。
ブラウザの横幅を狭くしていくと、コンテンツ内のメニューが消えて、ドロワーメニューのアイコンが現れます。
パッと切り替わるより、もうちょっと自然な感じに切り替わるようにしてみたいですね。CSSの指定を以下のように変えてみます。
.open {
transform: translate(0, -100%);
}
#drawer:checked + .open {
transform: translate(250px, 0);
}
@media (max-width: 480px) {
.open {
transform: translate(0, 0);
}
}display: noneで急に消すんじゃなくて、要素の透明度や位置を調整して隠すようにしてみました。それぞれtransitionプロパティを指定してゆっくり隠れるようにしています。

パララックス