サイトアイコン ayame.space

Sass(CSS)とjQueryだけでドロワーメニュー

レスポンシブデザインに欠かせないドロワーメニュー(ボタンを押すと横から飛び出してくるメニュー)をプラグインやフレームワークなしのCSS3とjQueryだけで使えるようにした。

参考URLのコードをかなり流用させていただきました。ほぼSassに書き換えただけです。

目次

環境

実装

CSS3でアニメーションとかも全て定義している。#hamburgerを押すとbodyに.drawer-openedを追加することによってドロワーを開く。

HTML

まずベースとなるHTMLを用意する。


<!doctype html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="stylesheet" href="css/main.css" type="text/css">
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <title>Title</title>
</head>
<body>
    <div id="mainwrap">
        <header>
            <h1>Logo</h1>
        </header>
        <nav>
            <ul>
                <li><a href="/">Menu Item</a></li>
            </ul>
        </nav>
        <div id="hamburger">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
        </div>
        <div id="content">
            Contents
        </div>
        <footer>
            <p><small>Copyright</small></p>
        </footer>
        <div id="overlay"></div>
    </div>
</body>
</html>

Sass

Sassでデザインやアニメーションを定義する。


$drawerwidth: 240px;

@mixin drawerAnimation{
    -webkit-transition: all 400ms cubic-bezier(1.000, 0.000, 0.000, 1.000); 
    -moz-transition: all 400ms cubic-bezier(1.000, 0.000, 0.000, 1.000); 
    -o-transition: all 400ms cubic-bezier(1.000, 0.000, 0.000, 1.000); 
    transition: all 400ms cubic-bezier(1.000, 0.000, 0.000, 1.000);
    
    -webkit-transition-timing-function: cubic-bezier(1.000, 0.000, 0.000, 1.000); 
    -moz-transition-timing-function: cubic-bezier(1.000, 0.000, 0.000, 1.000); 
    -o-transition-timing-function: cubic-bezier(1.000, 0.000, 0.000, 1.000); 
    transition-timing-function: cubic-bezier(1.000, 0.000, 0.000, 1.000);
}

body{
    &.drawer-opened{
        div#mainwrap{
            left: -$drawerwidth;
            box-shadow: 1px 0 2px #000000;
            -webkit-box-shadow: 1px 0 2px #000000;
        }
        header{
            left: -$drawerwidth;
        }
        nav{
            right: 0;
        }
        #hamburger :nth-child(1){
            transform:translate(0,8px) rotate(45deg);
            -webkit-transform:translate(0,8px) rotate(45deg);
        }
        #hamburger :nth-child(2){
            transform:translate(-20px ,0);
            -webkit-transform:translate(-20px ,0);
            opacity:0;
        }
        #hamburger :nth-child(3){
            transform:translate(0,-8px) rotate(-45deg);
            -webkit-transform:translate(0,-8px) rotate(-45deg);
        }
        #overlay{
            z-index: 3;
            opacity: 0.3;
            left: -$drawerwidth;
        }
    }
}

div#mainwrap{
    width: 100%;
    position: relative;
    padding-top: 50px;
    z-index: 2;
    left: 0;
    @include drawerAnimation;
}

header{
    background-color: #ff00ff;
    position: fixed;
    top: 0;
    left: 0;
    right: inherit;
    width: 100%;
    height: 50px;
    z-index: 2;
    @include drawerAnimation;
}

nav{
    position: fixed;
    top: 0;
    right: -$drawerwidth;
    width: $drawerwidth;
    height: 100%;
    background: #ffff00;
    z-index: 1;
    padding-top: 40px;
    @include drawerAnimation;
}

#hamburger{
    display: block;
    position: fixed;
    top: 0;
    right: 0;
    z-index: 3;
    width: 45px;
    padding: 17px 10px 10px;
    cursor: pointer;
    box-sizing: border-box;
    span{
        height: 2px;
        background: #FFFFFF;
        display: block;
        margin-bottom: 6px;
        @include drawerAnimation;
    }
}

#overlay{
    display: block;
    z-index:-1;
    opacity: 0;
    background: #000000;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    position: fixed;
    @include drawerAnimation;
}

JavaScript

最後にjQueryで#hamburgerを押したときの挙動を制御。


$(function(){
    ;(function($){
        var touch = false;
        $('#hamburger').on('click touchstart',function(e){
            switch (e.type) {
                case 'touchstart':
                    drawerToggle();
                    touch = true;
                    return false;
                break;
                case 'click':
                    if(!touch)
                         drawerToggle();
                    return false;
                break;
             }
            function drawerToggle(){
                $('body').toggleClass('drawer-opened');
                touch = false;
            }
        })
        $('#overlay').on('click touchstart',function(){
            $('body').removeClass('drawer-opened');
        })
    })(jQuery);
});

参考

モバイルバージョンを終了