RYX

Blog

Web制作 — 2026.02.05

【コピペOK】モダンなハンバーガーメニュー5選

← ブログ一覧に戻る

はじめに

ハンバーガーメニューの実装は、HTMLとCSSの基礎は理解できても、スムーズなアニメーションやレスポンシブ対応となると、思うように実装できないものですよね。

特に、ポートフォリオサイトではモダンで印象的なUIを実現したくても、JavaScriptを使った実装方法や、アクセシビリティに配慮したコーディングとなると、なかなか難しいものです。

この記事では、現場で使える5種類のハンバーガーメニューを、コピー&ペーストで実装できるようにご紹介します。

パターン1:基本的なスライドインメニュー

<div class="header">
  <button class="hamburger" aria-label="メニュー" aria-controls="nav-menu" aria-expanded="false">
    <span class="hamburger__line"></span>
    <span class="hamburger__line"></span>
    <span class="hamburger__line"></span>
  </button>

<nav id="nav-menu" class="nav" aria-hidden="true"> <ul class="nav__list"> <li class="nav__item"><a href="#" class="nav__link">ホーム</a></li> <li class="nav__item"><a href="#" class="nav__link">about</a></li> <li class="nav__item"><a href="#" class="nav__link">サービス</a></li> <li class="nav__item"><a href="#" class="nav__link">お問い合わせ</a></li> </ul> </nav> </div>

.header {
  position: relative;
  padding: 20px;
}

.hamburger { position: fixed; top: 20px; right: 20px; z-index: 100; width: 48px; height: 48px; border: none; background: transparent; cursor: pointer; }

.hamburger__line { position: absolute; left: 11px; width: 26px; height: 2px; background-color: #333; transition: all .4s; }

.hamburger__line:nth-of-type(1) { top: 14px; } .hamburger__line:nth-of-type(2) { top: 23px; } .hamburger__line:nth-of-type(3) { top: 32px; }

/* メニューオープン時 */ .hamburger.active .hamburger__line:nth-of-type(1) { transform: translateY(9px) rotate(-45deg); } .hamburger.active .hamburger__line:nth-of-type(2) { opacity: 0; } .hamburger.active .hamburger__line:nth-of-type(3) { transform: translateY(-9px) rotate(45deg); }

.nav { position: fixed; top: 0; left: 0; width: 300px; height: 100vh; background-color: #fff; box-shadow: 2px 0 4px rgba(0,0,0,.1); transform: translateX(-100%); transition: transform .4s; z-index: 90; }

.nav.active { transform: translateX(0); }

.nav__list { margin: 0; padding: 100px 0 0; list-style: none; }

.nav__item { padding: 0 20px; }

.nav__link { display: block; padding: 15px 0; color: #333; text-decoration: none; border-bottom: 1px solid #eee; }

// script.js
document.addEventListener('DOMContentLoaded', () => {
  const hamburger = document.querySelector('.hamburger');
  const nav = document.querySelector('.nav');

hamburger.addEventListener('click', () => { hamburger.classList.toggle('active'); nav.classList.toggle('active');

// アクセシビリティ対応
const isOpen = hamburger.classList.contains(&apos;active&apos;);
hamburger.setAttribute(&apos;aria-expanded&apos;, isOpen);
nav.setAttribute(&apos;aria-hidden&apos;, !isOpen);

});

// メニューの外側をクリックした時の処理 document.addEventListener('click', (e) => { if (!e.target.closest('.nav') && !e.target.closest('.hamburger') && nav.classList.contains('active')) { hamburger.classList.remove('active'); nav.classList.remove('active'); hamburger.setAttribute('aria-expanded', false); nav.setAttribute('aria-hidden', true); } }); });

実装のポイント解説:

  1. アクセシビリティへの配慮
  • aria-label属性でボタンの役割を明示
  • aria-expanded属性でメニューの開閉状態を通知
  • aria-hidden属性でスクリーンリーダーへの表示制御
  1. スムーズなアニメーション
  • transformとtransitionを使用した滑らかな動き
  • ハンバーガーアイコンの×への変形アニメーション
  1. レスポンシブ対応
  • vw/vh単位を使用した画面サイズ対応
  • メディアクエリは不要な最小限の実装
  1. UX向上のための実装
  • メニュー外クリックでの閉じる機能
  • タッチデバイスでの操作性考慮

パターン2:オーバーレイ&円形展開メニュー


<div class="header">
  <button class="hamburger-overlay" aria-label="メニュー" aria-controls="overlay-menu" aria-expanded="false">
    <span class="hamburger-overlay__line"></span>
    <span class="hamburger-overlay__line"></span>
    <span class="hamburger-overlay__line"></span>
  </button>

<nav id="overlay-menu" class="nav-overlay" aria-hidden="true"> <div class="nav-overlay__content"> <ul class="nav-overlay__list"> <li class="nav-overlay__item"><a href="#" class="nav-overlay__link">ホーム</a></li> <li class="nav-overlay__item"><a href="#" class="nav-overlay__link">サービス</a></li> <li class="nav-overlay__item"><a href="#" class="nav-overlay__link">works</a></li> <li class="nav-overlay__item"><a href="#" class="nav-overlay__link">お問い合わせ</a></li> </ul> </div> </nav> </div>

/* overlay-styles.css */
.hamburger-overlay {
  position: fixed;
  top: 20px;
  right: 20px;
  z-index: 1000;
  width: 48px;
  height: 48px;
  border: none;
  background: transparent;
  cursor: pointer;
}

.hamburger-overlay__line { position: absolute; left: 11px; width: 26px; height: 2px; background-color: #333; transition: all .6s; }

.hamburger-overlay__line:nth-of-type(1) { top: 14px; } .hamburger-overlay__line:nth-of-type(2) { top: 23px; } .hamburger-overlay__line:nth-of-type(3) { top: 32px; }

.hamburger-overlay.active .hamburger-overlay__line { background-color: #fff; }

.hamburger-overlay.active .hamburger-overlay__line:nth-of-type(1) { transform: translateY(9px) rotate(-45deg); } .hamburger-overlay.active .hamburger-overlay__line:nth-of-type(2) { opacity: 0; } .hamburger-overlay.active .hamburger-overlay__line:nth-of-type(3) { transform: translateY(-9px) rotate(45deg); }

.nav-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100vh; background-color: rgba(0, 0, 0, 0.95); visibility: hidden; opacity: 0; transition: all .6s; z-index: 900; }

.nav-overlay.active { visibility: visible; opacity: 1; }

.nav-overlay__content { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 100%; text-align: center; }

.nav-overlay__list { margin: 0; padding: 0; list-style: none; }

.nav-overlay__item { opacity: 0; transform: translateY(20px); transition: all .6s; }

.nav-overlay.active .nav-overlay__item { opacity: 1; transform: translateY(0); }

.nav-overlay.active .nav-overlay__item:nth-child(1) { transition-delay: 0.1s; } .nav-overlay.active .nav-overlay__item:nth-child(2) { transition-delay: 0.2s; } .nav-overlay.active .nav-overlay__item:nth-child(3) { transition-delay: 0.3s; } .nav-overlay.active .nav-overlay__item:nth-child(4) { transition-delay: 0.4s; }

.nav-overlay__link { display: inline-block; padding: 20px; color: #fff; font-size: 24px; text-decoration: none; transition: color .3s; }

.nav-overlay__link:hover { color: #4a90e2; }

// overlay-script.js
document.addEventListener('DOMContentLoaded', () => {
  const hamburger = document.querySelector('.hamburger-overlay');
  const nav = document.querySelector('.nav-overlay');

hamburger.addEventListener('click', () => { hamburger.classList.toggle('active'); nav.classList.toggle('active');

const isOpen = hamburger.classList.contains(&apos;active&apos;);
hamburger.setAttribute(&apos;aria-expanded&apos;, isOpen);
nav.setAttribute(&apos;aria-hidden&apos;, !isOpen);

// メニューオープン時に背景スクロールを防止
document.body.style.overflow = isOpen ? &apos;hidden&apos; : &apos;&apos;;

});

// ESCキーでメニューを閉じる document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && nav.classList.contains('active')) { hamburger.classList.remove('active'); nav.classList.remove('active'); hamburger.setAttribute('aria-expanded', false); nav.setAttribute('aria-hidden', true); document.body.style.overflow = ''; } }); });

実装のポイント:

  1. スムーズなオーバーレイ表示
  • visibility と opacity の組み合わせによるスムーズな表示/非表示
  • transition-delay を使用したメニュー項目の段階的な表示
  1. アクセシビリティ強化
  • ESCキーでのメニュー閉じる機能
  • スクロール制御による背景固定
  • キーボード操作のサポート
  1. 視覚的な工夫
  • メニュー項目の段階的なフェードイン
  • ホバー時のインタラクション
  • 背景の透過による奥行き表現

パターン3:モーフィングアニメーションメニュー

<div class="header">
  <button class="hamburger-morph" aria-label="メニュー" aria-controls="morph-menu" aria-expanded="false">
    <svg class="hamburger-morph__icon" width="48" height="48" viewBox="0 0 100 100">
      <path class="hamburger-morph__line" d="M 20,29 H 80 C 80,29 94.5,28.817352 94.532987,66.711331 94.543142,77.980673 90.966081,81.670246 85.259173,81.668997 79.552261,81.667751 75.000211,74.999942 75.000211,74.999942 L 25.000021,25.000058" />
      <path class="hamburger-morph__line" d="M 20,50 H 80" />
      <path class="hamburger-morph__line" d="M 20,71 H 80 C 80,71 94.5,71.182648 94.532987,33.288669 94.543142,22.019327 90.966081,18.329754 85.259173,18.331003 79.552261,18.332249 75.000211,25.000058 75.000211,25.000058 L 25.000021,74.999942" />
    </svg>
  </button>

<nav id="morph-menu" class="nav-morph" aria-hidden="true"> <div class="nav-morph__wrapper"> <ul class="nav-morph__list"> <li class="nav-morph__item"> <a href="#" class="nav-morph__link"> <span class="nav-morph__text">Home</span> <span class="nav-morph__hover">ホーム</span> </a> </li> <li class="nav-morph__item"> <a href="#" class="nav-morph__link"> <span class="nav-morph__text">About</span> <span class="nav-morph__hover">私たちについて</span> </a> </li> <li class="nav-morph__item"> <a href="#" class="nav-morph__link"> <span class="nav-morph__text">Works</span> <span class="nav-morph__hover">制作実績</span> </a> </li> <li class="nav-morph__item"> <a href="#" class="nav-morph__link"> <span class="nav-morph__text">Contact</span> <span class="nav-morph__hover">お問い合わせ</span> </a> </li> </ul> </div> </nav> </div>

.hamburger-morph {
  position: fixed;
  top: 20px;
  right: 20px;
  z-index: 1000;
  width: 48px;
  height: 48px;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
}

.hamburger-morph__icon { width: 100%; height: 100%; }

.hamburger-morph__line { fill: none; stroke: #000; stroke-width: 6; transition: stroke-dasharray 600ms cubic-bezier(0.4, 0, 0.2, 1), stroke-dashoffset 600ms cubic-bezier(0.4, 0, 0.2, 1); }

.hamburger-morph__line:nth-child(1) { stroke-dasharray: 60 207; }

.hamburger-morph__line:nth-child(2) { stroke-dasharray: 60 60; }

.hamburger-morph__line:nth-child(3) { stroke-dasharray: 60 207; }

.hamburger-morph.active .hamburger-morph__line:nth-child(1) { stroke-dasharray: 90 207; stroke-dashoffset: -134; }

.hamburger-morph.active .hamburger-morph__line:nth-child(2) { stroke-dasharray: 1 60; stroke-dashoffset: -30; }

.hamburger-morph.active .hamburger-morph__line:nth-child(3) { stroke-dasharray: 90 207; stroke-dashoffset: -134; }

.nav-morph { position: fixed; top: 0; left: 0; width: 100%; height: 100vh; background: rgba(29, 29, 31, 0.98); clip-path: circle(0% at calc(100% - 44px) 44px); transition: clip-path 0.7s cubic-bezier(0.4, 0, 0.2, 1); z-index: 900; }

.nav-morph.active { clip-path: circle(150% at calc(100% - 44px) 44px); }

.nav-morph__wrapper { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; }

.nav-morph__list { margin: 0; padding: 0; list-style: none; text-align: center; }

.nav-morph__item { opacity: 0; transform: translateY(30px); transition: opacity 0.4s ease, transform 0.4s ease; }

.nav-morph.active .nav-morph__item { opacity: 1; transform: translateY(0); }

.nav-morph.active .nav-morph__item:nth-child(1) { transition-delay: 0.3s; } .nav-morph.active .nav-morph__item:nth-child(2) { transition-delay: 0.4s; } .nav-morph.active .nav-morph__item:nth-child(3) { transition-delay: 0.5s; } .nav-morph.active .nav-morph__item:nth-child(4) { transition-delay: 0.6s; }

.nav-morph__link { position: relative; display: inline-block; padding: 20px; font-size: 28px; color: #fff; text-decoration: none; overflow: hidden; }

.nav-morph__text, .nav-morph__hover { display: block; transition: transform 0.3s ease; }

.nav-morph__hover { position: absolute; top: 100%; left: 0; width: 100%; transform: translateY(0%); }

.nav-morph__link:hover .nav-morph__text { transform: translateY(-100%); }

.nav-morph__link:hover .nav-morph__hover { transform: translateY(-100%); }

document.addEventListener('DOMContentLoaded', () => {
  const hamburger = document.querySelector('.hamburger-morph');
  const nav = document.querySelector('.nav-morph');

hamburger.addEventListener('click', () => { hamburger.classList.toggle('active'); nav.classList.toggle('active');

const isOpen = hamburger.classList.contains(&apos;active&apos;);
hamburger.setAttribute(&apos;aria-expanded&apos;, isOpen);
nav.setAttribute(&apos;aria-hidden&apos;, !isOpen);
document.body.style.overflow = isOpen ? &apos;hidden&apos; : &apos;&apos;;

});

// メニューリンクのホバーエフェクト用のイベントリスナー const menuLinks = document.querySelectorAll('.nav-morph__link'); menuLinks.forEach(link => { link.addEventListener('mouseenter', () => { link.querySelector('.nav-morph__text').style.transform = 'translateY(-100%)'; link.querySelector('.nav-morph__hover').style.transform = 'translateY(-100%)'; });

link.addEventListener(&apos;mouseleave&apos;, () =&gt; {
  link.querySelector(&apos;.nav-morph__text&apos;).style.transform = &apos;translateY(0)&apos;;
  link.querySelector(&apos;.nav-morph__hover&apos;).style.transform = &apos;translateY(0)&apos;;
});

}); });

実装のポイント:

  1. SVGを使用したモーフィングアニメーション
  • stroke-dasharray と stroke-dashoffset を使用した滑らかな変形
  • cubic-bezier による緩急のある動き
  1. クリエイティブなメニュー展開
  • clip-path を使用した円形展開アニメーション
  • 順次表示されるメニュー項目
  1. インタラクティブな要素
  • 二重テキストによるホバーエフェクト
  • スムーズなテキストスライド

パターン4:スライド&フェードメニュー

<div class="header">
  <button class="hamburger-fade" aria-label="メニュー" aria-controls="fade-menu" aria-expanded="false">
    <div class="hamburger-fade__wrapper">
      <span class="hamburger-fade__line"></span>
      <span class="hamburger-fade__line"></span>
      <span class="hamburger-fade__line"></span>
    </div>
  </button>

<nav id="fade-menu" class="nav-fade" aria-hidden="true"> <div class="nav-fade__bg"></div> <div class="nav-fade__wrapper"> <ul class="nav-fade__list"> <li class="nav-fade__item"> <span class="nav-fade__number">01</span> <a href="#" class="nav-fade__link">Home</a> </li> <li class="nav-fade__item"> <span class="nav-fade__number">02</span> <a href="#" class="nav-fade__link">About</a> </li> <li class="nav-fade__item"> <span class="nav-fade__number">03</span> <a href="#" class="nav-fade__link">Works</a> </li> <li class="nav-fade__item"> <span class="nav-fade__number">04</span> <a href="#" class="nav-fade__link">Contact</a> </li> </ul> <div class="nav-fade__info"> <p class="nav-fade__address">東京都渋谷区○○ 1-2-3</p> <p class="nav-fade__tel">03-1234-5678</p> </div> </div> </nav> </div>

/* fade-styles.css */
.hamburger-fade {
  position: fixed;
  top: 20px;
  right: 20px;
  z-index: 1000;
  width: 60px;
  height: 60px;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
}

.hamburger-fade__wrapper { position: relative; width: 30px; height: 20px; margin: 20px auto; }

.hamburger-fade__line { position: absolute; left: 0; width: 100%; height: 2px; background-color: #333; transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1); }

.hamburger-fade__line:nth-child(1) { top: 0; } .hamburger-fade__line:nth-child(2) { top: 9px; } .hamburger-fade__line:nth-child(3) { top: 18px; }

.hamburger-fade.active .hamburger-fade__line { background-color: #fff; }

.hamburger-fade.active .hamburger-fade__line:nth-child(1) { transform: translateY(9px) rotate(45deg); }

.hamburger-fade.active .hamburger-fade__line:nth-child(2) { opacity: 0; transform: translateX(20px); }

.hamburger-fade.active .hamburger-fade__line:nth-child(3) { transform: translateY(-9px) rotate(-45deg); }

.nav-fade { position: fixed; top: 0; left: 0; width: 100%; height: 100vh; visibility: hidden; z-index: 900; }

.nav-fade__bg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.95); opacity: 0; transition: opacity 0.5s cubic-bezier(0.23, 1, 0.32, 1); }

.nav-fade.active { visibility: visible; }

.nav-fade.active .nav-fade__bg { opacity: 1; }

.nav-fade__wrapper { position: relative; display: flex; flex-direction: column; justify-content: center; width: 100%; height: 100%; padding: 5vh 10vw; }

.nav-fade__list { margin: 0; padding: 0; list-style: none; }

.nav-fade__item { position: relative; margin-bottom: 2vh; padding-left: 60px; opacity: 0; transform: translateY(20px); transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1); }

.nav-fade.active .nav-fade__item { opacity: 1; transform: translateY(0); }

.nav-fade.active .nav-fade__item:nth-child(1) { transition-delay: 0.2s; } .nav-fade.active .nav-fade__item:nth-child(2) { transition-delay: 0.3s; } .nav-fade.active .nav-fade__item:nth-child(3) { transition-delay: 0.4s; } .nav-fade.active .nav-fade__item:nth-child(4) { transition-delay: 0.5s; }

.nav-fade__number { position: absolute; left: 0; color: #666; font-size: 14px; font-family: 'Roboto', sans-serif; }

.nav-fade__link { display: inline-block; color: #fff; font-size: 32px; text-decoration: none; transition: color 0.3s ease; }

.nav-fade__link:hover { color: #4a90e2; }

.nav-fade__info { margin-top: auto; padding-left: 60px; color: #666; font-size: 14px; opacity: 0; transform: translateY(20px); transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1) 0.6s; }

.nav-fade.active .nav-fade__info { opacity: 1; transform: translateY(0); }

.nav-fade__address, .nav-fade__tel { margin: 5px 0; }

@media (max-width: 768px) { .nav-fade__link { font-size: 24px; }

.nav-fade__item { padding-left: 40px; margin-bottom: 1.5vh; }

.nav-fade__info { padding-left: 40px; } }

// fade-script.js
document.addEventListener('DOMContentLoaded', () => {
  const hamburger = document.querySelector('.hamburger-fade');
  const nav = document.querySelector('.nav-fade');

hamburger.addEventListener('click', () => { hamburger.classList.toggle('active'); nav.classList.toggle('active');

const isOpen = hamburger.classList.contains(&apos;active&apos;);
hamburger.setAttribute(&apos;aria-expanded&apos;, isOpen);
nav.setAttribute(&apos;aria-hidden&apos;, !isOpen);
document.body.style.overflow = isOpen ? &apos;hidden&apos; : &apos;&apos;;

});

// メニューリンクにホバーエフェクトを追加 const menuLinks = document.querySelectorAll('.nav-fade__link'); menuLinks.forEach(link => { link.addEventListener('mouseover', () => { const number = link.parentElement.querySelector('.nav-fade__number'); number.style.color = '#4a90e2'; });

link.addEventListener(&apos;mouseout&apos;, () =&gt; {
  const number = link.parentElement.querySelector(&apos;.nav-fade__number&apos;);
  number.style.color = &apos;#666&apos;;
});

}); });

実装のポイント:

  1. 高級感のある演出
  • 番号とテキストの組み合わせ
  • 連続的なアニメーション
  • 洗練された配色
  1. レスポンシブ対応
  • フォントサイズの可変
  • パディングの調整
  • メディアクエリによる最適化
  1. インタラクティブ要素
  • 番号とリンクの連動したホバーエフェクト
  • スムーズなフェードイン
  • 背景のオーバーレイ効果

パターン5:グリッドアニメーションメニュー

<div class="header">
  <button class="hamburger-grid" aria-label="メニュー" aria-controls="grid-menu" aria-expanded="false">
    <div class="hamburger-grid__dots">
      <span class="hamburger-grid__dot"></span>
      <span class="hamburger-grid__dot"></span>
      <span class="hamburger-grid__dot"></span>
      <span class="hamburger-grid__dot"></span>
      <span class="hamburger-grid__dot"></span>
      <span class="hamburger-grid__dot"></span>
      <span class="hamburger-grid__dot"></span>
      <span class="hamburger-grid__dot"></span>
      <span class="hamburger-grid__dot"></span>
    </div>
  </button>

<nav id="grid-menu" class="nav-grid" aria-hidden="true"> <div class="nav-grid__content"> <div class="nav-grid__sections"> <section class="nav-grid__section"> <h2 class="nav-grid__title">Menu</h2> <ul class="nav-grid__list"> <li><a href="#" class="nav-grid__link">Home</a></li> <li><a href="#" class="nav-grid__link">About</a></li> <li><a href="#" class="nav-grid__link">Works</a></li> <li><a href="#" class="nav-grid__link">Contact</a></li> </ul> </section>

    &lt;section class=&quot;nav-grid__section&quot;&gt;
      &lt;h2 class=&quot;nav-grid__title&quot;&gt;Social&lt;/h2&gt;
      &lt;ul class=&quot;nav-grid__list&quot;&gt;
        &lt;li&gt;&lt;a href=&quot;#&quot; class=&quot;nav-grid__link&quot;&gt;Twitter&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;#&quot; class=&quot;nav-grid__link&quot;&gt;Instagram&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;#&quot; class=&quot;nav-grid__link&quot;&gt;GitHub&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/section&gt;
  &lt;/div&gt;
&lt;/div&gt;

</nav> </div>

.hamburger-grid {
  position: fixed;
  top: 20px;
  right: 20px;
  z-index: 1000;
  width: 50px;
  height: 50px;
  padding: 10px;
  border: none;
  background: transparent;
  cursor: pointer;
}

.hamburger-grid__dots { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; width: 100%; height: 100%; }

.hamburger-grid__dot { width: 100%; height: 100%; background-color: #333; border-radius: 50%; transition: transform 0.3s ease, background-color 0.3s ease; }

.hamburger-grid.active .hamburger-grid__dot { background-color: #fff; }

.hamburger-grid.active .hamburger-grid__dot:nth-child(1) { transform: scale(0); } .hamburger-grid.active .hamburger-grid__dot:nth-child(2) { transform: translateY(8px); } .hamburger-grid.active .hamburger-grid__dot:nth-child(3) { transform: scale(0); } .hamburger-grid.active .hamburger-grid__dot:nth-child(4) { transform: translateX(8px); } .hamburger-grid.active .hamburger-grid__dot:nth-child(5) { transform: scale(1.2); } .hamburger-grid.active .hamburger-grid__dot:nth-child(6) { transform: translateX(-8px); } .hamburger-grid.active .hamburger-grid__dot:nth-child(7) { transform: scale(0); } .hamburger-grid.active .hamburger-grid__dot:nth-child(8) { transform: translateY(-8px); } .hamburger-grid.active .hamburger-grid__dot:nth-child(9) { transform: scale(0); }

.nav-grid { position: fixed; top: 0; left: 0; width: 100%; height: 100vh; background-color: #1a1a1a; visibility: hidden; opacity: 0; transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1); z-index: 900; }

.nav-grid.active { visibility: visible; opacity: 1; }

.nav-grid__content { display: grid; grid-template-columns: repeat(12, 1fr); gap: 20px; max-width: 1200px; height: 100%; margin: 0 auto; padding: 100px 40px; }

.nav-grid__sections { grid-column: span 12; display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 40px; }

.nav-grid__section { opacity: 0; transform: translateY(20px); transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1); }

.nav-grid.active .nav-grid__section { opacity: 1; transform: translateY(0); }

.nav-grid.active .nav-grid__section:nth-child(1) { transition-delay: 0.2s; } .nav-grid.active .nav-grid__section:nth-child(2) { transition-delay: 0.3s; }

.nav-grid__title { margin: 0 0 20px; color: #666; font-size: 14px; text-transform: uppercase; letter-spacing: 2px; }

.nav-grid__list { margin: 0; padding: 0; list-style: none; }

.nav-grid__list li { margin-bottom: 15px; overflow: hidden; }

.nav-grid__link { display: inline-block; color: #fff; font-size: 24px; text-decoration: none; transform: translateY(100%); transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1), color 0.3s ease; }

.nav-grid.active .nav-grid__link { transform: translateY(0); }

.nav-grid__link:hover { color: #4a90e2; }

@media (max-width: 768px) { .nav-grid__content { padding: 80px 20px; }

.nav-grid__sections { grid-template-columns: 1fr; }

.nav-grid__link { font-size: 20px; } }

document.addEventListener('DOMContentLoaded', () => {
  const hamburger = document.querySelector('.hamburger-grid');
  const nav = document.querySelector('.nav-grid');
  const links = document.querySelectorAll('.nav-grid__link');

hamburger.addEventListener('click', () => { hamburger.classList.toggle('active'); nav.classList.toggle('active');

const isOpen = hamburger.classList.contains(&apos;active&apos;);
hamburger.setAttribute(&apos;aria-expanded&apos;, isOpen);
nav.setAttribute(&apos;aria-hidden&apos;, !isOpen);
document.body.style.overflow = isOpen ? &apos;hidden&apos; : &apos;&apos;;

// リンクのアニメーションディレイを設定
if (isOpen) {
  links.forEach((link, index) =&gt; {
    link.style.transitionDelay = `${0.2 + (index * 0.1)}s`;
  });
} else {
  links.forEach(link =&gt; {
    link.style.transitionDelay = &apos;0s&apos;;
  });
}

});

// アクセシビリティのためのキーボードナビゲーション nav.addEventListener('keydown', (e) => { if (e.key === 'Escape' && nav.classList.contains('active')) { hamburger.click(); } }); });

実装のポイント:

  1. グリッドレイアウトの活用
  • CSS Gridによる柔軟なレイアウト
  • レスポンシブ対応の簡略化
  • セクション分けによる整理された構造
  1. ドットアニメーション
  • 個別のドットの動きによる視覚的な楽しさ
  • スケールと移動を組み合わせた演出
  • 滑らかな色の変化
  1. 段階的なアニメーション
  • セクションごとの表示タイミング制御
  • リンクの順次表示
  • スムーズな出現と消失

さいごに

ここまで5種類のモダンなハンバーガーメニューの実装方法をご紹介してきました。

それぞれのデザインや動きの特徴を活かして、サイトの雰囲気に合わせて使い分けてください。

Contact

Shopifyのご相談はこちら

構築・移行・改修・運用改善まで。状況を伺って最短ルートをご提案します。

相談・見積もり無料 / 24時間以内に返信

相談する