jQueryとCSSでスライドメニューを作る

端的に言うとBootstrapのOff Canvas的なアレです。ボタンを押すと横からスライドして現れるメニュー。BootstrapのはPCのように広い画面では最初からメニューが表示されてて、モバイルだとか狭い画面でメニューが表示しきれなくなると、メニューを表示するボタンが出るんだよね。いや、それは確かに合理的でその通りなんだけど、PCでも必要ない時は隠しておいてより広く画面を使いたい場面もあると思うので試しに作ってみた。PCだろうがモバイルだろうがメニューは最初から表示しない。ボタンを押された時に初めて表示される。 slidemenu
こういうの。関係ないけど試しにアニメーションGIF作ってみたら色が残念なことに。GIFだから仕方ないね。
簡単な内容の説明
しかし、全然エレガントじゃく力技だけど。分かりやすいように色を付けてあるので何となく動きは分かるんじゃないかと思う。段階的な動きは次のような感じ。
クラス名 内容
.cover-layer 画面全体を覆うボックス
.content コンテンツ表示エリア
.slide-menu スライドメニューの内容
  • 初期状態は.cover-layerを非表示。また、.slide-menuは画面外の表示位置(left: -100)にしておく。
  • ボタンが押されたら.cover-layerを表示して、画面外に置いてあった.slide-menuを画面内にスライド(left=-100 → left=0)させてくるだけ。それと同時に.contentと.conver-layerも横にスライド(left=0 → .slide-menuの幅)させる。
  • メニューを閉じる時は.cover-layerが押されたら、表示された時と逆方向にスライドさせて.conver-layerを非表示にする。
<!DOCTYPE html>
<html lang="jp">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>SlideMenu</title>
    <script type="text/javascript" src="js/jquery-3.1.1.min.js"></script>
  </head>
  <body>

    <style>
    html, body {
      height: 100%;
      margin: 0;
      padding: 0;
    }

    .cover-layer {
      position: fixed;
      height: 100%;
      width: 100%;
      top: 0;
      left: 0;
      background: #DFF0D8;
      opacity: 0.6;
      display: none;
    }

    .content {
      position: fixed;
      height: 100%;
      width: 100%;
      top: 0;
      left: 0;
      background: #D9EDF7;
    }

    .slide-menu {
      position: fixed;
      height: 100%;
      top: 0;
      left: -100px;
      background: #F2DEDE;
    }
    </style>

    <script>
      $(function() {
        $('#menu-open').on('click', function () {
          if ($('.cover-layer').css('display') == 'none') {
            var width = $('.slide-menu').outerWidth();
            $('.cover-layer').show();
            $('.cover-layer').animate({'left': width}, {duration: 200});
            $('.content').animate({'left': width}, {duration: 200});
            $('.slide-menu').animate({'left': 0}, {duration: 200});
          }
        });

        $('.cover-layer').on('click', function () {
          var width = $('.slide-menu').outerWidth();
          $('.cover-layer').animate({'left': 0}, {duration: 200});
          $('.content').animate({'left': 0}, {duration: 200});
          $('.slide-menu').animate({'left': -width}, {duration: 200});
          $('.cover-layer').hide();
        });
      });
    </script>

    <div class="content">
      <div class="cover-layer"></div>
      <button id="menu-open" type="button">≡</button>
      <div>コンテンツ</div>
    </div>

    <div class="slide-menu">
      <p><a href="#">メニュー1</a></p>
      <p><a href="#">メニュー2</a></p>
      <p><a href="#">メニュー3</a></p>
    </div>

  </body>
</html>