Webパーツ辞典

ハンバーガーメニューHamburger menu

横三本線のアイコンを押すとメニューが開く仕掛け。線がバンズと具に見えることからこの名前になった。

表示例

アイコン: Font Awesome 7 Free(fa-solid / fa-regular)

別名・英語表記

  • 三本線メニュー
  • ハンバーガーボタン
  • メニューボタン
  • ドロワーの開閉ボタン
  • ハンバーガーメニューボタン
  • Hamburger menu

実装例

<div class="x-hamburger">
  <button class="x-hamburger__b" type="button" aria-expanded="true" aria-controls="x-hamburger-panel">
    <i class="fa-solid fa-bars" aria-hidden="true"></i>
    <span>メニュー</span>
  </button>
  <!-- 見本なので開いた状態。本文を押し下げる作りでは、閉じるときに hidden 属性を付け、ボタンの aria-expanded を false にする。
       本文の上に重ねる作りではパネルに popover 属性を付け、hidden 属性は使わない(併せると開いても表示されない) -->
  <nav class="x-hamburger__panel" id="x-hamburger-panel" aria-label="メインメニュー">
    <ul>
      <li><a href="/about/">特徴</a></li>
      <li><a href="/price/">料金</a></li>
      <li><a href="/faq/">よくある質問</a></li>
    </ul>
  </nav>
</div>

AIへの指示文

「ハンバーガーメニュー(Hamburger menu)」を実装してください。

## これは何か
横三本線のアイコンを押すとメニューが開く仕掛け。線がバンズと具に見えることからこの名前になった。

## 使いどころ
- 画面が狭くて、メニューを常時出しておけないとき
- メニューの項目が多く、普段は畳んでおきたいとき

## 実装の要件
- button + aria-expanded + aria-controls
- 本文を押し下げて開くなら、JavaScript でパネルの hidden 属性とボタンの aria-expanded を同時に付け替える。CSS だけのチェックボックス方式は状態を伝えられない
- 本文の上に重ねて開くなら、パネルに popover 属性、ボタンに popovertarget を付ける。Esc・外側クリックで閉じる動きはブラウザが持つ(Chrome・Edge は 114 から、Safari は 17 から、Firefox は 125 から。iOS の Safari が外側のタップで閉じるのは 18.3 から)
- 本文の上に重ねる popover の作りでは、aria-expanded をパネルの toggle イベントの newState(open / closed)に合わせて true / false に書き換え、外側クリックや Esc で閉じたときも古い値を残さない
- 重ねる作りでは、ボタンの click で先に this.focus() を呼ぶ。Safari と macOS の Firefox はマウスで押したボタンにフォーカスを移さず、そのままだとパネルの中から Esc で閉じたときにボタンへ戻らない
- popover のパネルは既定で position: fixed; inset: 0; margin: auto; のため画面の中央に出る。ヘッダーの下に横いっぱいで出すなら inset: auto; top: ヘッダーの高さ; left: 0; right: 0; width: auto; margin: 0; のように上書きする
- 何が入っているか分からないので、押される回数はメニューを出しっぱなしにした場合より減る。主要導線は外に出す
- アイコンだけだと気づかれないことがある。「メニュー」の文字を添えると押されやすい
- 開いたときに閉じる手段(×・背景クリック・Escキー)を必ず用意する

## アクセシビリティの要件
- button 要素で作り、aria-expanded で開閉状態を持つ
- aria-controls で開く対象の id を指すと、対応関係が伝わる
- 開いている間は Esc キーで閉じられるようにし、閉じたらボタンへフォーカスを戻す

## 参考にする実装
この形を出発点にして、プロジェクトの命名規則・色・余白に合わせて調整してください。

```html
<div class="x-hamburger">
  <button class="x-hamburger__b" type="button" aria-expanded="true" aria-controls="x-hamburger-panel">
    <i class="fa-solid fa-bars" aria-hidden="true"></i>
    <span>メニュー</span>
  </button>
  <!-- 見本なので開いた状態。本文を押し下げる作りでは、閉じるときに hidden 属性を付け、ボタンの aria-expanded を false にする。
       本文の上に重ねる作りではパネルに popover 属性を付け、hidden 属性は使わない(併せると開いても表示されない) -->
  <nav class="x-hamburger__panel" id="x-hamburger-panel" aria-label="メインメニュー">
    <ul>
      <li><a href="/about/">特徴</a></li>
      <li><a href="/price/">料金</a></li>
      <li><a href="/faq/">よくある質問</a></li>
    </ul>
  </nav>
</div>
```

```css
/* 貼った先のリセットに頼らないよう、この部品の中だけ border-box にする */
.x-hamburger,
.x-hamburger *:not([class*="fa-"]),
.x-hamburger *:not([class*="fa-"])::before,
.x-hamburger *:not([class*="fa-"])::after {
  box-sizing: border-box;
  /* 貼った先の既定の書体に引きずられないようにする。書体が変わると
     文字の幅と高さが変わり、枠のサイズまでずれる */
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Hiragino Sans", "Noto Sans JP", "Yu Gothic UI", Meiryo, sans-serif;
}

.x-hamburger {
  /* 貼った先で幅いっぱいに伸びないよう、中身の幅に合わせる */
  display: inline-block;
}
.x-hamburger__b {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid #cfd4dc;
  border-radius: 8px;
  background: #fff;
  color: #1b2028;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.x-hamburger__b:hover {
  border-color: #1d4ed8;
  color: #1d4ed8;
}
.x-hamburger__b:focus-visible {
  outline: 2px solid #1d4ed8;
  outline-offset: 2px;
}
.x-hamburger__panel {
  /* 押し下げる作りでは、閉じているときは hidden 属性で隠す(JS で付け外しする)。popover の作りでは hidden を使わない */
  margin-top: 6px;
  padding: 5px;
  border: 1px solid #e3e6ea;
  border-radius: 8px;
  background: #fff;
}
.x-hamburger__panel ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.x-hamburger__panel a {
  display: block;
  padding: 5px 8px;
  border-radius: 6px;
  font-size: 12px;
  color: #1b2028;
  text-decoration: none;
}
.x-hamburger__panel a:hover {
  background: #f1f3f6;
}
```

## 出力の約束
- HTML と CSS を分けて出す。JavaScript が要るときは素の JavaScript で書き、UIフレームワークは使わない。
- 参考実装がアイコンに Font Awesome のクラスを使っている場合は、プロジェクトで使っているアイコンかインライン SVG に置き換えてよい。
- 上のアクセシビリティ要件を満たす。満たせない箇所があるときは、理由を添えて先に知らせる。
- 色・角丸・余白は既存のデザイントークンがあればそれを使う。無ければ CSS 変数として切り出す。

使いどころ

  • 画面が狭くて、メニューを常時出しておけないとき
  • メニューの項目が多く、普段は畳んでおきたいとき

注意点

  • 何が入っているか分からないので、押される回数はメニューを出しっぱなしにした場合より減る。主要導線は外に出す
  • アイコンだけだと気づかれないことがある。「メニュー」の文字を添えると押されやすい
  • 開いたときに閉じる手段(×・背景クリック・Escキー)を必ず用意する

アクセシビリティの要点

  • button 要素で作り、aria-expanded で開閉状態を持つ
  • aria-controls で開く対象の id を指すと、対応関係が伝わる
  • 開いている間は Esc キーで閉じられるようにし、閉じたらボタンへフォーカスを戻す

見分け方

関連するパーツ