ハンバーガーアイコンの☓になる動き、横からメニューが出てくる動き、メニューが出てるときはメインエリアを暗くすることまで、すべてCSSのみで実装可能。
See the Pen drawer menu by himeka223 (@himeka223) on CodePen.
解説
CSSのみで作るドロワーメニューの動きは、inputタグのcheckboxで制御している。
- チェックがされた場合… メニュー横から出現、アイコンを☓に、メインエリアを暗く。
- チェックがはずれた場合… すべてもとに戻る。
checkbox と label の連動
checkbox を label と連動させ、
labelのクリックで、checkboxにチェックが入るように。
<!-- checkbox自体は非表示 -->
<input class="l-drawer__checkbox" id="drawerCheckbox" type="checkbox" >
<!-- ハンバーガーアイコン -->
<label class="l-drawer__icon" for="drawerCheckbox">
<span class="l-drawer__icon-parts"></span>
</label>
<!-- 背景を暗く -->
<label class="l-drawer__overlay" for="drawerCheckbox"></label>
アイコンとの連動
inputタグの**id="drawerCheckbox"と、labelタグのfor="drawerCheckbox"で同じ値を設定することで、inputとlabelを紐付け、連動をさせている。**
暗くなる背景との連動
1つのinputのcheckboxに複数labelを連動できるので、背景を暗くするエリアをlabelとし、**for="drawerCheckbox"**で、連動させ、ここをクリックしてもチェックが外れるようにしている。
checkboxの非表示
labelに連動させることで、checkboxの表示は不要なので、display: noneで非表示にしておく。
ハンバーガーアイコン
アイコンもCSSで実装している。
<!-- ハンバーガーアイコン -->
<label class="l-drawer__icon" for="drawerCheckbox">
<span class="l-drawer__icon-parts"></span>
</label>
// ハンバーガーアイコン
&__icon{
cursor: pointer;
display: block;
width: 56px;
height: 60px;
position: fixed;
right: 0;
// ハンバーガーアイコンの中の線
&-parts,
&-parts:before,
&-parts:after{
background-color: #000;
display: block;
width: 26px;
height: 2px;
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
margin: auto;
}
&-parts:before,
&-parts:after{
content: " ";
}
&-parts:before{
top: 16px
}
&-parts:after{
top: -16px
}
}
label
ハンバーガーアイコンの外枠
- アイコンの大きさを決めブロック要素にする。
-
position: fixedで、位置を、ブラウザ自体に固定する。(今回は右上に固定するため、right: 0指定) -
cursor: pointer;でホバー時のカーソルを矢印でなく、指マークにする。
span(labelの子要素)
ハンバーガーアイコンの三本線部分。
span自体で、真ん中の線を作り、spanのafterとbeforeの疑似要素で、で上の線と下の線を作っている。
- 線1本の**長さ・太さを
widthとheight**で決める。色はbackground-colorで指定。 -
position: absolute;とmargin: autoでlabelの中の上下中央揃えにする。 - 上下の線
:afterと:beforeは**疑似要素なので、content: " "**を指定。 - 上下の線の位置を、**上は
top: -16pxと下はtop: -16px**というように、移動させることで、三本線に。
オーバーレイ
メニューが開いてるときは、メインエリアを暗くする。
// ドロワーメニュー開いた時のメインエリアを暗く
&__overlay{
background: #000;
opacity: 0;
// display: none; //opacity: 0;で非表示はできているため、display: none;は削除
pointer-events: none; //ポインタの動作全部無効化
width: 100%;
height: 100%;
position: fixed;
top: 0;
right: 0;
}
* メニューが開かれる前は非表示にするため**opacty: 0とdisplay: none;を設定する
- **
width: 100%;、height: 100%;**を指定し、メインエリア全体にかかるように。 -
position: fixed;でブラウザに固定表示。
08/22 コメントにて下記ご指摘を頂きました。ありがとうございます。
-
pointer-events: none;でポインタの動作を無効化する。 -
opacity: 0;で非表示はできているため、display: none;の記載はいらない。
メニュー
// ドロワーメニュー
&__menu{
background: #ffffff;
color: #000;
max-width: 100%;
width: 320px;
height: 100vh;
overflow-y: auto; //スクロール
-webkit-overflow-scrolling: touch; //スクロール(SP)
position: fixed;
top: 0;
right: -320px;
}
- メニューが見えづらいので背景色を指定。
-
widthでメニューの幅、heightでメニューの高さの指定。100vhとすることでブラウザの高さ分の値が取れる。 -
overflow-y: auto;と-webkit-overflow-scrolling: touch;を指定して、メニュー内のみスクロールできるようにする。 -
position: fixed;でブラウザ自体に固定。 -
right: -320pxでメニュー幅分、右端からさらにに移動させることで、クリック前はメニューを隠す。
:checked ~ で、クリック後のスタイルを指定
checkboxに対して、**:checked**をつけると、チェックボックスにチェックが入ってる時だけの指定が出来る。
~セレクタは、同じ階層で、後に出てくる要素すべてを指定する。
この2つを組み合わせ、:checked ~ と指定すると、チェックボックスにチェックが入ってる時、同階層であとに出てくる要素への指定ができる。
今回は、上で説明した、ハンバーガーアイコン、オーバーレイ、メニューのクリック後のスタイルを設定する必要がある。
クリック後のハンバーガーアイコン
// ハンバーガーアイコン
.l-drawer__icon{
.l-drawer__icon-parts{
background: transparent;
}
.l-drawer__icon-parts:before{
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
top: 0;
}
.l-drawer__icon-parts:after{
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
top: 0;
}
}
- 真ん中の線は、
background: transparent;で背景を透過させ見えなくする。 - 上下の線は、
top: 0;で位置を戻し、transform: rotate(-45deg);で、それぞれ45°回転させる。
クリック後のオーバーレイ
// メインエリアを暗くする
.l-drawer__overlay {
opacity: 0.3;
pointer-events: auto; //ポインタの動作デフォルトに戻す
}
* display: block;とopacity: 0.3;で表示させる
08/22 コメントにて下記ご指摘を頂きました。ありがとうございます。
-
pointer-events: none;でポインタの動作を無効化してたのをautoにしてデフォルトに戻す。 -
opacity: 0.3;で表示はできているため、display: block;の記載はいらない。
クリック後のメニュー
// メニューをだす
.l-drawer__menu {
right: 0;
}
- 左にマイナスで隠してため、
right: 0に指定して、位置を右端に揃える
z-indexで重なりを調整
// z-indexの指定(1がメインエリア)
&__icon{
z-index: 4;
}
&__menu{
z-index: 3;
}
&__overlay{
z-index: 2;
}
- メインエリアガ一番下として、**
オーバーレイ→メニュー→ハンバーガーアイコン**となるように調整 - まとめて書くことで調整しやすくする。
transitionで動きをスムーズに
// 動きをスムーズに
&__icon-parts,
&__icon-parts:after,
&__icon-parts:before,
&__overlay,
&__menu{
-webkit-transition: all .7s ;
transition: all .7s ;
}
- 同じスピードでと動くようにまとめて記載。
-
allですべての変化するプロパティに、.7sで0.7秒かけて変化する指定。
まとめ
inputのcheckboxやradioを使えばjsを使わなくてもCSSでできることが増えそう。
同じような考えでモーダルも実装可能である。
参考サイト
ドロワーやモーダルをCSSだけで実現する方法 | HPcode
CSSだけで簡単!ハンバーガーメニューの作り方(スマホ対応)