みったに

レスポンシブなハンバーガーメニューをjQueryとCSSで実装する方法【コピペOK】

JQUERY PROGRAMMING

こんにちは、みったに(@mittani_s)です。

今回は、ハンバーガーメニューの実装方法について書きます。コピペでスグに実装できます。

  • ハンバーガーメニューってよく聞くけど、難しそう、、、
  • パソコンとスマホで分けるの面倒そう、、、
  • できるだけ簡単に実装したい!

僕がこういった悩み持っていたときに、コピペですぐ使えるコードがサクッと拾えたら良いなと思っていたので、コードセットとして残しておきます。

レスポンシブなハンバーガーメニューをjQueryとCSSで実装する方法


今回は、下記のようなメニューを作っていきます。

ちなみに、ハンバーガーメニューとは、画面サイズを小さくしたときに、右上に出ている3本線のマークのことです。

スマホのサイズにすると、横幅が狭くなるので、こういった形でメニューを圧縮しているわけですね。そして、そこをクリックしたときに、メニューが出てくるという形です。今ではかなり一般的な形になっているかなと思います。

レスポンシブなハンバーガーメニューのコード

では、早速コードを書いていきます。下記のとおりです。

HTMLのコード


    <div class="contents">
      <div class="menu_wrapper">
        <a class="menu">
          <span class="menu__line menu__line--top"></span>
          <span class="menu__line menu__line--center"></span>
          <span class="menu__line menu__line--bottom"></span>
        </a>
      </div>
      <nav class="gnav">
        <div class="gnav__wrap">
          <ul class="gnav__menu">
            <li class="gnav__menu__item gnav__menu__item--list">
              <a href="#">TOP</a>
            </li>
            <li class="gnav__menu__item gnav__menu__item--list">
              <a href="#">ABOUT</a>
            </li>
            <li class="gnav__menu__item gnav__menu__item--list">
              <a href="#">WORK</a>
              <ul class="gnav__child__menu">
                <li class="gnav__child_menu_item gnav__menu__item--list">
                  <a href="#">
                    <span>WORK1</span>
                  </a>
                </li>
                <li class="gnav__child_menu_item gnav__menu__item--list">
                  <a href="#">
                    <span>WORK2</span>
                  </a>
                </li>
                <li class="gnav__child_menu_item gnav__menu__item--list">
                  <a href="#">
                    <span>WORK3</span>
                  </a>
                </li>
              </ul>
            </li>
            <li class="gnav__menu__item gnav__menu__item--list">
              <a href="#">SERVICE</a>
              <ul class="gnav__child__menu">
                <li class="gnav__child_menu_item gnav__menu__item--list">
                  <a href="#">
                    <span>SERVICE1</span>
                  </a>
                </li>
                <li class="gnav__child_menu_item gnav__menu__item--list">
                  <a href="#">
                    <span>SERVICE2</span>
                  </a>
                </li>
                <li class="gnav__child_menu_item gnav__menu__item--list">
                  <a href="#">
                    <span>SERVICE3</span>
                  </a>
                </li>
              </ul>
            </li>
            <li class="gnav__menu__item gnav__menu__item--list">
              <a href="#">CONTACT</a>
            </li>
          </ul>
        </div>
      </nav>
    </div>
    <!-- JS -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="style.js"></script>
  

こういった感じです。
スマホでもPCでも同じHTMLコードを使用します。

CSSのコード

@charset "UTF-8";
/*===================
 Reset  
===================*/
/* このResetの部分は自由にカスタマイズしてください */
ul,
li,
a,
label {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
}

body {
  line-height: 2;
  -webkit-text-size-adjust: 100%;
  color: #444;
  font-family: Noto, "Hiragino Sans", Helvetica, Arial, sans-serif;
  -webkit-transition-duration: 0.3s;
          transition-duration: 0.3s;
}

ol,
ul {
  list-style: none;
}

blockquote,
q {
  quotes: none;
}

blockquote:before,
blockquote:after,
q:before,
q:after {
  content: "";
  content: none;
}

table {
  border-collapse: collapse;
  border-spacing: 0;
}

a,
a:visited {
  color: inherit;
}

a {
  text-decoration: none;
}

:after,
:before {
  -webkit-box-sizing: inherit;
  box-sizing: inherit;
}

.animate__animated {
  opacity: 0;
}

.contents {
  height: 1000px;
}

/*===================
グローバルメニュー
===================*/
.gnav__menu {
  position: relative;
}

.gnav__wrap {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-wrap: wrap;
      flex-wrap: wrap;
  -webkit-box-pack: justify;
      -ms-flex-pack: justify;
          justify-content: space-between;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  height: 100%;
}

.gnav__menu {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  width: 100%;
  -webkit-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
}

.gnav__menu__item {
  margin-right: 30px;
  padding-bottom: 13px;
  padding-top: 15px;
  display: inline-block;
}

.gnav__menu__item > a,
.gnav__menu__item > span {
  display: inline-block;
  padding-bottom: 2px;
}

.gnav__menu__item:hover > a,
.gnav__menu__item:hover > span {
  border-bottom: #666 1px solid;
  margin-bottom: -1px;
}

.gnav__menu__item:last-child {
  margin-right: 0px;
}

.gnav__child__menu {
  display: none;
  position: absolute;
  top: 55px;
  opacity: 0;
}

@-webkit-keyframes fadeIn {
  0% {
    opacity: 0;
    -webkit-transform: translateY(5px);
            transform: translateY(5px);
  }
  100% {
    opacity: 1;
    -webkit-transform: translateY(0px);
            transform: translateY(0px);
  }
}

@keyframes fadeIn {
  0% {
    opacity: 0;
    -webkit-transform: translateY(5px);
            transform: translateY(5px);
  }
  100% {
    opacity: 1;
    -webkit-transform: translateY(0px);
            transform: translateY(0px);
  }
}

.gnav__menu__item:hover > .gnav__child__menu {
  -webkit-animation-name: fadeIn;
          animation-name: fadeIn;
  -webkit-animation-duration: 0.5s;
          animation-duration: 0.5s;
  -webkit-animation-fill-mode: forwards;
          animation-fill-mode: forwards;
  display: block;
}

.gnav__child_menu_item {
  width: 100%;
  min-width: 140px;
  background-color: #000;
  text-align: center;
  opacity: 0.7;
}

.gnav__child_menu_item a {
  display: block;
  font-size: 14px;
  padding: 10px;
}

.gnav__child_menu_item:hover {
  background: #000;
  opacity: 1;
}

.gnav__child_menu_item:hover a > span {
  border-bottom: #fff 1px solid;
  margin-bottom: -1px;
  display: inline-block;
  padding-right: 5px;
  padding-left: 5px;
}

/*==================
ハンバーガーメニュー
===================*/
.menu_wrapper {
  display: none;
  margin-left: auto;
}

@media screen and (max-width: 1024px) {
  .scroll-prevent {
    position: fixed;
    width: 100%;
    height: 100%;
    left: 0;
  }
  .menu_wrapper {
    position: relative;
    width: 40px;
    height: 40px;
    background: inherit;
    z-index: 999;
    -webkit-transition: 0.3s;
    transition: 0.3s;
    display: block;
    margin-right: 0;
  }
  .menu {
    height: 20px;
    position: absolute;
    right: 5px;
    top: 9px;
    width: 25px;
    z-index: 9999;
  }
  .menu__line {
    background: #333;
    display: block;
    height: 2px;
    position: absolute;
    -webkit-transition: -webkit-transform 0.3s;
    transition: -webkit-transform 0.3s;
    transition: transform 0.3s;
    transition: transform 0.3s, -webkit-transform 0.3s;
    width: 82%;
  }
  .menu__line--center {
    top: 9px;
  }
  .menu__line--bottom {
    bottom: 0;
  }
  .menu__line--top.active {
    top: 8px;
    -webkit-transform: rotate(45deg);
    transform: rotate(45deg);
    background: #6c5534;
  }
  .menu__line--center.active {
    -webkit-transform: scaleX(0);
    transform: scaleX(0);
  }
  .menu__line--bottom.active {
    bottom: 10px;
    -webkit-transform: rotate(135deg);
    transform: rotate(135deg);
    background: #6c5534;
  }
  .gnav {
    width: 100%;
    max-width: none;
    font-size: 14px;
  }
  .gnav__menu,
  .gnav__child__menu {
    display: inline-block;
    width: auto;
    width: 90%;
  }
  .gnav__child__menu {
    position: static;
    opacity: 1;
  }
  .gnav__menu__item:hover > .gnav__child__menu {
    -webkit-animation: none;
            animation: none;
  }
  .gnav__menu__item:hover > a,
  .gnav__menu__item:hover > span {
    border-bottom: none;
    margin-bottom: 0px;
  }
  .gnav__child_menu_item {
    width: 100%;
    min-width: none;
    background-color: inherit;
    text-align: center;
  }
  .gnav__child_menu_item a {
    font-size: 14px;
  }
  .gnav__child_menu_item:hover {
    background: inherit;
    opacity: 1;
  }
  .gnav__child_menu_item:hover a > span {
    border-bottom: none;
    margin-bottom: 0px;
    padding-right: 0;
    padding-left: 0;
  }
  .header .gnav__menu li,
  .header .gnav__child__menu li {
    margin-right: 0;
  }
  .gnav {
    background-color: #f4f4f4;
    /* 背景色を設定 */
    background-size: cover;
    background-position: center;
    display: none;
    height: 100%;
    position: fixed;
    width: 100%;
    z-index: 98;
    top: 0;
    left: 0;
    opacity: 1;
    overflow-y: scroll;
  }
  .gnav__wrap {
    -webkit-box-align: center;
        -ms-flex-align: center;
            align-items: center;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    height: 100%;
    position: absolute;
    width: 100%;
  }
  .gnav__menu {
    position: absolute;
    top: 10px;
    left: 20px;
  }
  .gnav__menu__item,
  .gnav__child_menu_item {
    margin: 5px 0;
    opacity: 0;
    text-align: left;
    padding-left: 16px;
    display: block;
  }
  .gnav__menu__item {
    border-bottom: 1px solid #666;
  }
  .gnav__child_menu_item {
    padding: 3px 0px 3px 24px;
  }
  .gnav__child_menu_item:first-child {
    padding-top: 16px;
    border-top: 0.1px solid #666;
  }
  .gnav__menu__item:last-child {
    border: none;
  }
  .gnav__menu__item a,
  .gnav__menu__item span,
  .gnav__child_menu_item a {
    color: #333;
    font-size: 16px;
    font-weight: 500;
    text-decoration: none;
    -webkit-transition: 0.5s;
    transition: 0.5s;
    letter-spacing: 0.2em;
    display: block;
  }
  .gnav__child_menu_item a {
    font-size: 14px;
    padding: 0;
  }
}

CSSは、わりと丸ごと貼っているので、不要なところは削除しつつ、自分に合うようにカスタマイズして使ってみてください。

最後にjQueryです。

jQueryのコード

// ********************
// ハンバーガーメニュー
// ********************
var navFlg = false; /* フラグの初期化 */
var scrollPosition; /* フラグの初期化 */
$(".menu").on("click", function () {
  // .menuをクリックしたらactiveの切り替え(ハンバーガーを回転)
  $(".menu__line").toggleClass("active");
  // ナビの表示・非表示の切り替え
  $(".gnav").fadeToggle();
  if (!navFlg) {
    $(".gnav__menu__item--list").each(function (i) {
      $(this)
        .delay(i * 50)
        .animate(
          {
            opacity: 1,
          },
          200
        );
    });
    scrollPosition = $(window).scrollTop();
    $(".body").addClass("scroll-prevent").css({ top: -scrollPosition });
    navFlg = true;
  } else {
    $(".gnav__menu__item--list").css({
      opacity: 0,
    });
    $(".body").removeClass("scroll-prevent").css({ top: 0 });
    window.scrollTo(0, scrollPosition);
    navFlg = false;
  }
});
// 同一ページへのリンクでも動作するように追加
$(".gnav__menu__item--list").on("click", function () {
  if (navFlg) {
    $(".menu__line").toggleClass("active");
    $(".gnav").fadeToggle();
    $(".gnav__menu__item--list").css({
      opacity: 0,
    });
    $(".body").removeClass("scroll-prevent").css({ top: 0 });
    window.scrollTo(0, scrollPosition);
    navFlg = false;
  }
});

こういった感じです。

これでコピペだけで、ハンバーガーメニューが作れるはずです。
疑問点や誤り等のご指摘がありましたら、お問い合わせいただけますと、とても嬉しいです。

それでは、今回は以上となります。
ここまでお読みいただき、ありがとうございました🙇‍♂️