ハンバーガーメニューの実装(jQuery編)

ロッチくん
ロッチくん

スマホ表示になった際などによくあるナビゲーションメニューであるハンバーガーメニューの作り方を知りたいニャ

最初はjQueryでOK

もしあなたがWEB制作だけを極めたいと考えている場合、多くのJavascriptを覚える必要はなく、必要最低限の頻出パーツをjQueryで覚えておくことが最短の道のりになります。

jQueryを用いた頻出UIまとめた記事はこちらから!最低限こちらを実装できればWEB制作の現場でもそんなに困らないかと思います!!

もちろん世間的に脱jQueryの動きがあるので最終的にはバニラJSによる実装を視野に入れるべきですが、WEB制作の領域で必要とされる動的なパーツはかなり絞られますので、最初は理解できなくてもコピペでもいいので扱えるようにしていきましょう。

今回は主にスマホなどでよく見るハンバーガーメニューの実装を見ていきたいと思います。

ハンバーガーメニューとは

ハンバーガーメニュー(hamburger menu)とは、主に三本線のアイコンで表されるナビゲーションメニューのことです。三本線のアイコン「≡」がハンバーガーに似ていることから、この名前が付けられました。

スマホサイトで設置されることが主流でしたが、近年ではPCサイトでもよく見られるようになっています。

この三本線のアイコンをクリックすることで、画面外からメニューが出てくるためスペースを上手に活用して画面上をすっきりさせるとこができます。

メニューの実装方法

それでは具体的に設置方法を見ていきましょう。
こちらがデモサイトになります。

まずはjQueryの読み込みをして準備を整えましょう。

HTML

<div class="wrapper">
    <header>
        <div class="header-inner">
            <h1>LOGO</h1>
            <button class="burgerBtn">
                <span class="burgerLine"></span>
            </button>
            <nav class="drawerNav">
                <ul>
                    <li>ドロワーメニュ-1</li>
                    <li>ドロワーメニュ-2</li>
                    <li>ドロワーメニュ-3</li>
                    <li>ドロワーメニュ-3</li>
                </ul>
            </nav>
            <div class="overlay"></div>
        </div>
    </header>

    <div class="container">
        <section class="contents"></section>
        <section class="contents"></section>
        <section class="contents"></section>    
    </div>
</div>

CSS

html {
  scrollbar-gutter: stable;
}
body.noScroll {
  overflow: hidden;
}
.wrapper {
  overflow: hidden;
}
header {
  width: 100%;
  height: 65px;
  background-color: rgb(52, 52, 238);
  color: #fff;
  position: relative;
}
.header-inner {
  max-width: 1000px;
  height: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 15px;
  margin: 0 auto;
}
h1 {
  font-size: 18px;
  font-weight: bold;
}
.drawerNav {
  position: fixed;
  top: 0;
  right: 0;
  width: 480px;
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  z-index: 10;
  background-color: #fff;
  color: #333;
  border: 25px solid rgb(52, 52, 238);
  border-right: 42px solid rgb(52, 52, 238);
  border-top: 65px solid rgb(52, 52, 238);
  transform: translateX(100%);
  transition: all .3s;
}
.drawerNav.open {
  transform: translateX(0);
}
.drawerNav ul li:not(:last-of-type) {
  margin-bottom: 25px;
}
.overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-color: rgba(0,0,0,.6);
  z-index: 9;
  opacity: 0;
  visibility: hidden;
  transition: all .3s;
}
.overlay.show {
  opacity: 1;
  visibility: visible;
}
.burgerBtn {
  width: 45px;
  height: 45px;
  cursor: pointer;
  display: block;
  position: relative;
  z-index: 20;
}
.burgerLine {
  width: 100%;
  height: 3px;
  background-color: #fff;
  display: block;
  position: relative;
  transition: all .3s;
}
.burgerLine::before,
.burgerLine::after {
  content: "";
  display: block;
  background-color: #fff;
  position: absolute;
  left: 0;
  width: 100%;
  height: 100%;
  transition: all .3s;
}
.burgerLine::before {
  top: -15px;
}
.burgerLine::after {
  top: 15px;
}
.burgerBtn.clicked {
  position: fixed;
  top: 8px;
  right: 429px;
}
.burgerBtn.clicked .burgerLine {
  background-color: transparent;
}
.burgerBtn.clicked .burgerLine::before {
  top: 0;
  transform: rotate(45deg);
}
.burgerBtn.clicked .burgerLine::after {
  top: 0;
  transform: rotate(-45deg);
}

.container {
  max-width: 1000px;
  margin: 0 auto;
}
section.contents {
  width: 100%;
  height: 500px;
  background-color: rgb(59, 221, 167);
  border-radius: 15px;
  margin: 50px 0;
}

JavaScript

$('.burgerBtn').on('click', function() {
  $(this).toggleClass('clicked');
  $('.drawerNav').toggleClass('open');
  $('.overlay').toggleClass('show');
  $('body').toggleClass('noScroll');
});
$('.overlay').on('click', function() {
  $(this).removeClass('show');
  $('.burgerBtn').removeClass('clicked');
  $('.drawerNav').removeClass('open');
  $('body').removeClass('noScroll');
});

ちょこっと解説

ハンバーガーメニュー(hamburger menu)の三本線のアイコン「≡」は色々な実装方法があって、そのアニメーションもやろうと思えば様々なバリエーションがあります。今回は非常にシンプルかつ分かりやすい方法で実装してみました。

三本線の描写

三本線はまず真ん中の線を<span></span>一つをHTMLに記述した上で、CSSで疑似要素の「::before」と「::after」を使って上下の線をそれぞれ描写しています。疑似要素をそれぞれ「position: absolute;」とし基準となる真ん中の線に対しての絶対配置としたことで、最初はtopをそれぞれ-15px、15pxとしていたところから、クリック後のクロスする動きの際に、top位置を0に戻しそれぞれ45度と-45度傾けることで「≡」から「×」へとアニメーションさせています。

この三本線のアイコンを描写するときに<div>を使ったり<span>を三個並べたり色々手法はあるのですが、このクリックした後のアニメーションで45度と-45度傾けるアニメーションは共通であるものの、上下の線にy軸方向の動きをつけるものに関してはその理屈がややわかりにくいなと感じていたので、今回の実装方法がベストであると感じています。

今回の方法もy軸方向への動きはあるものの、形を「×」に変化させるため、いったん絶対配置である真ん中の線と同じ位置に戻す=「top: 0;」とするためシンプルでわかりやすいと感じています。

また、今回ドロワーメニュー表示した際にスクロールをロックする動きを入れています。

bodyに「overflow: hidden;」を指定することでスクロールできない状態にしているのですが、そのことで、右横にあるスクロールバーが消えスクロールバーの幅分画面ががたつくことになります。

scrollbar-gutterは、スクロールバー出現分の余白を制御できるプロパティで、bodyが「overflow: hidden;」となりスクロールバーがなくなった分のスペースを確保してくれるというわけです。

ただ、今のところscrollbar-gutterは現在Safariでは利用できないようです。

ハンバーガーメニュー自体はスマホでの実装が多いか、PC版でも全画面に表示されることが多いためその場合はスクロールバーを考慮する必要もないので基本的にはこちらを気にする状況はあまりないと思いますが、念のため。

最後に

三本線の実装からクロスアニメーションであったり、JSの記述もシンプルなクラスの付け外しであったりと、ハンバーガーメニューの実装は基本中の基本ですが案外奥が深いのでこれからもバニラJSでの実装含め様々な方法を紹介していければと考えております!

jQueryを用いた頻出UIまとめた記事はこちらから!最低限こちらを実装できればWEB制作の現場でもそんなに困らないかと思います!!

コメント

タイトルとURLをコピーしました