checkboxを使ってCSSだけでハンバーガーメニュー

CSS だけでハンバーガーメニューを設置する という記事を以前書いたのですが、iPhone など CSS のセレクタで hover が効かないデバイスではメニューが開きませんでした。今回の記事はそれを解消すべく input 要素の checkbox を使う事で、hover ではなく click に反応するようにして iPhone でも CSS だけでメニューが開くようにしてみます。

当然、iPhone 以外の PC ブラウザ、アンドロイドでも問題なく開閉します。

check-and-hamburger

checkbox って?

checkbox とは input 要素で選ぶことが出来る種類の1つで、下のデモのようにクリックすることで 〆 マークがついたり消えたりする要素です。アンケートやフォームなどでよく使われれています。

input 要素に共通して言えることですが、label 要素というのを個々に設定することが出来ます。label とはその input 要素の名前などを入れることが出来る要素で、例えば checkbox に label 要素を「チェックボックス」として付けた場合、チェックボックス本体だけでなく、label 要素、つまり「チェックボックス」の文字列をクリクしてもボックス本体のマークがついたり消えたりします。

デモ

デモの HTML

<input id="demo" type="checkbox" value="off"><label for="demo">チェックボックス</label>

input 要素の id と label 要素の for の値をそろえることで一体化させることが出来ます。 label 要素の「チェックボックス」の文字列をクリックしてもマークがつくことが確認できますね。

この特性を使ってハンバーガーメニューを作ってみます。実際にこのページでも右上にハンバーガーメニューを設置してみました。

hamburgermenu

ハンバーガーメニューの作り方

HTML

<input id="menu-cb" type="checkbox" value="off">
<label id="menu-icon" for="menu-cb">≡</label>
<label id="menu-background" for="menu-cb"></label>
<div id="ham-menu">
    <ul>
        <li>メニュー1</li>
        <li>メニュー2</li>
        <li>メニュー3</li>
    </ul>
</div>

CSS

#ham-menu {
    background-color: #fff; /*メニュー背景色*/
    box-sizing: border-box;
    height: 100%;
    padding: 10px 40px; /*メニュー内左右上下余白*/
    position: fixed;
    right: -300px; /*メニュー横幅 width と合わせる*/
    top: 0;
    transition: transform 0.3s linear 0s; /*0.3s はアニメーションにかかる時間*/
    width: 300px; /*メニュー横幅*/
    z-index: 1000;
}

#menu-background {
    background-color: #333; /*黒背景*/
    display: block;
    height: 100%;
    opacity: 0;
    position: fixed;
    right: 0;
    top: 0;
    transition: all 0.3s linear 0s; /*0.3s はアニメーションにかかる時間*/
    width: 100%;
    z-index: -1;
}

#menu-icon {
    background-color: #fff; /*アイコン部分背景色*/
    border-radius: 0 0 0 10px; /*左下角丸*/
    color: #333; /*アイコン(フォント)色*/
    cursor: pointer;
    display: block;
    font-size: 50px; /*アイコン(フォント)サイズ*/
    height: 50px; /*アイコン縦高さ*/
    line-height: 50px; /*縦位置中央化*/
    position: fixed;
    right: 0;
    text-align: center;
    top: 0;
    width: 50px; /*アイコン横幅*/
    transition: all 0.3s linear 0s; /*0.3s はアニメーションにかかる時間*/
    z-index: 1000;
}

#menu-cb {
    display: none; /*チェックボックス本体は消しておく*/
}

#menu-cb:checked ~ #ham-menu,
#menu-cb:checked ~ #menu-icon {
    transform: translate(-300px); /*メニュー本体横幅 width と合わせる*/
}

#menu-cb:checked ~ #menu-background {
    opacity: 0.5;
    z-index: 999;
}

HTML のポイントは label を2つ配置し、片方を「≡」のアイコン用、もう片方を黒背景用にします。2つ label 要素を使っていいのか定かではありませんが、for の値を設定することでどちらも label として機能します。

CSS の疑似セレクタに :checked というものがあり、チェックボックスがチェックされてる状態を指定できるものがあります。label 要素である ≡ アイコンをクリックするとチェックボックスがチェックされてメニューが開く仕組みです。

黒背景自体も label 要素にすることで ≡ アイコンだけでなく、黒背景をクリックしてもメニューが閉じるようになっています。これは label 要素である黒背景がチェックボックス本体と同じ機能をもっているためです。そして、チェックボックス本体は display:none で消しておきます。CSS で消しても label をクリックすることでチェックの有無が切り替わります。

まとめ

前回の記事で iPhone だけメニューが開閉しないので悲しい感じでしたが、これで iPhone でも CSS だけでハンバーガーメニューを設置出来ました。

checkbox でハンバーガーメニューを作ることの弱点は :checked が IE9 以上の対応なので古い IE には使えない事ぐらいです。特に問題はなさそうです。

before などの疑似要素を使ってクリックされると ≡ のアイコンを変化させたりなんかも出来そうです。

  • メニュー1
  • メニュー2
  • メニュー3