ハンバーガーアイコンの☓になる動き、横からメニューが出てくる動き、メニューが出てるときはメインエリアを暗くすることまで、すべて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だけで簡単!ハンバーガーメニューの作り方(スマホ対応)