「HTML」と「CSS」のみで実装する ハンバーガーメニュー【オフキャンバス編】

【オフキャンバス編】ハンバーガーメニュー 「HTML」と「CSS」のみで実装する

「Javascript」を使用しないハンバーガーメニューの実装方法について、以前の記事でご紹介しましたが、表示するドロワーメニューのアニメーションはバリエーションが豊富に存在します。

今回は、オフキャンバスと呼ばれる、画面全体が横にスライドしてメニューが表示されるタイプの実装方法をご紹介していきます。こちらも、「HTML」と「CSS」のみで設定することができ、基本的な方法の記述から少しの変更で実装可能です。

基本的なハンバーガーメニューの確認

ハンバーガーメニューの実装方法について確認していきましょう。以前の記事でご紹介した基本的な方法では、クリックして表示されるドロワーメニューのアニメーションは、メインのコンテンツを上から覆い被さるようにスライドインしてくるタイプでした。

下記の記事にサンプルもありますので、よろしければご確認ください。

【基本編】ハンバーガーメニュー 「HTML」と「CSS」のみで実装する

ハンバーガーメニューのHTML

<body>
    <header>
        <h1>ロゴ</h1>

        <div id="drawer">
            <input id="check_input" type="checkbox"> 
            <label id="menu_btn" for="check_input"> <!-- ハンバーガーボタン部分 -->
                <span></span>
            </label>
            <label id="drawer_back" for="check_input"></label> <!-- ドロワーメニューの背景部分 -->

            <div id="menu_cont"> <!-- ドロワーメニュー本体部分 -->
                <ul>
                    <li><a href="">HOME</a></li>
                    <li><a href="">COMPANY</a></li>
                    <li><a href="">ABOUT</a></li>
                    <li><a href="">ACCESS</a></li>
                    <li><a href="">CONTACT</a></li>
                </ul>
            </div>
        </div>
    </header>

    <main>
        <h2>メインコンテンツ</h2>
    </main>

    <footer>
        <h2>フッターコンテンツ</h2>
    </footer>

</body>

HTMLマークアップのポイントとして、input要素のchecked属性と、CSSの間接セレクタ(~)を利用してクリックイベントを実装するので、input要素とボタン部分となるlabel要素や、ドロワーメニューの本体部分(div)は、同じ階層にある必要がありました。

ハンバーガーメニューのCSS

/* input非表示 */
        #check_input {
            display: none;
        }

/* ハンバーガーボタン */
        #menu_btn {
            position: fixed;
            top: 30px;
            right: 30px;
            height: 60px;
            width: 60px;
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 100;
            background-color: #fff;
            cursor: pointer;
        }
       /* 三本線*/
        #menu_btn span,
        #menu_btn span::before,
        #menu_btn span::after {
            content: "";
            display: block;
            position: absolute;
            height: 3px;
            width: 25px;
            border-radius: 3px;
            background-color: #CE5D8B;
            transition: all 0.5s cubic-bezier(0.075, 0.82, 0.165, 1); /*アニメーションのイージングも設定しておく*/
        }
        #menu_btn span::before {
            bottom: 8px;
        }
        #menu_btn span::after {
            top: 8px;
        }

        /* クリックされたら三本線が×に変化する */
        #check_input:checked ~ #menu_btn span {
            background-color: transparent; 
        }
        #check_input:checked ~ #menu_btn span::before {
            bottom: 0;
            transform: rotate(45deg);
        }
        #check_input:checked ~ #menu_btn span::after {
            top: 0;
            transform: rotate(-45deg);
        }

/* ドロワーメニュー */
        #menu_cont {
            position: fixed;
            top: 0;
            left: 100%; /*left 100%で画面の外に出しておく*/
            width: 80%;
            height: 100%;
            background: #fff;
            z-index: 90;
            transition: left 0.5s cubic-bezier(0.075, 0.82, 0.165, 1);
        }

        /* ドロワーメニュー外の背景 */
        #drawer_back {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            z-index: 80;
        }

        /* メニューリストの装飾 */
        #menu_cont ul {
            padding: 10% 10% 0
        }
        #menu_cont ul li {
            list-style: none;
        }
        #menu_cont ul li a {
            display: block;
            width: 100%;
            padding: 10px;
            margin: 5px;
            color:#CE5D8B;
            text-decoration: none;
        }
        #menu_cont ul li a:hover {
            opacity: 0.7;
        }

        /* クリックされたらドロワーメニュー表示 */
        #check_input:checked ~ #menu_cont {
            left: 20%;
        }
        #check_input:checked ~ #drawer_back {
            display: block;
        }

オフキャンバスの実装における変更点

それでは、オフキャンバスの実装方法について見ていきましょう。

オフキャンバスのアニメーションとは、どのような動きになるのでしょうか。記事の冒頭でも触れましたが、コンテンツ全体が横(または縦)にスライドして画面からはみ出し、隠れていたメニュー部分が表示されるというものです。

これを行うには、基本的な方法のHTMLから、2点の変更が必要になります。

まずは、オフキャンバスタイプのHTMLを確認していきましょう。

オフキャンバスタイプのHTML

<body>
<!-- input・label・ドロワーメニューはbody直下に移動する -->
<input id="check_input" type="checkbox"> 
<label id="menu_btn" for="check_input"> <!-- ハンバーガーボタン部分 -->
    <span></span>
</label>
<label id="drawer_back" for="check_input"></label> <!-- ドロワーメニューの背景部分 -->

<div id="menu_cont"> <!-- ドロワーメニュー本体部分 -->
    <ul>
        <li><a href="">HOME</a></li>
        <li><a href="">COMPANY</a></li>
        <li><a href="">ABOUT</a></li>
        <li><a href="">ACCESS</a></li>
        <li><a href="">CONTACT</a></li>
    </ul>
</div>

<div id="wrapper"> <!-- コンテンツ部分をdivで囲む input要素と同じ階層に配置する -->
    <header>
        <h1>ロゴ</h1>
    </header>
    <main>
        <h2>メインコンテンツ</h2>
    </main>
    <footer>
        <h2>フッターコンテンツ</h2>
    </footer>
</div>

</body>

HTMLの変更点

  • ハンバーガーメニュー部分をbody直下に移動する … input要素やlabel要素・メニューリストなどは、header要素の中、div要素にまとめて設置していましたが、こちらをheaderの外、body要素の直下に移動します。
  • コンテンツ部分をdivで囲む … ページの主なコンテンツ部分全体(header ~ footer)をアニメーションさせる必要があるので、div要素で囲みます。input要素と同じ、body直下に配置します。

コンテンツ部分をアニメーションさせるには、input要素と同じ階層にある必要があります。上記2点の変更を行うことで、checked属性・CSS間接セレクタ(~)を利用したスタイルの変更が行えます。

オフキャンバスタイプの追加CSS

CSSの変更は、コンテンツ部分を囲んだdivの設定を追加するだけです。

/* wrapper コンテンツ */
#wrapper {
    position: relative;
    left: 0;
    transition: left 0.5s cubic-bezier(0.075, 0.82, 0.165, 1); /* ドロワーメニューと同じ設定にしておく */
}
#check_input:checked ~ #wrapper {
    left: -80%;
}

アニメーションのtransitionの設定は、ドロワーメニューの動きと同じにしておいてください。

コードサンプル

See the Pen off canvas Hamburger menu by web-basic-archive (@web-basic-archive) on CodePen.

メインコンテンツが画面外にスライドして、ドロワーメニューが表示されているのがお分かりいただけるでしょうか。

今回は基本タイプと同様に、ドロワーメニューが表示された際に、メインコンテンツ部分を暗くして、メニュー部分が目立つスタイルにしていますが、こちらの部分をなくすことで、よりオフキャンバスの動きが強調されますので、サイトのデザインに合わせて変更してみてください。

この他にも、ドロワーメニューの表示テクニック・アイディアは様々あり、公開されていますので、またの機会にご紹介していきたいと思います。

Follow me!