HTML/CSS

✅ 【HTML/CSS】ハンバーガーメニューを作るときにやりがちなNG構造と正しい書き方

こんにちは、コーダーのためのWeb制作ブログの中の人です!👋
今回は痛い失敗から学んだ教訓と、正しいハンバーガーメニューの実装方法を共有します!


まず例えで自分が初学者の頃やらかしてたダメなコードを書きます!

<!-- ❌ 初学者の頃私がやらかしたダメなコード --> 
<button class="header__nav-toggle">
 <div class="header__nav-toggle-hamburger"></div>
 <div class="header__nav-toggle-hamburger"></div>
 <div class="header__nav-toggle-hamburger"></div>
</button>

⚠️ なぜこれがダメなのか?現場で学んだ3つの理由

調べてみて初めて知った重要なこと:

1. HTMLの仕様違反だった

W3Cの仕様によると、buttonタグの中身は「フレージングコンテンツ」(テキストやインライン要素)だけが許可されています。divはブロック要素なので入れてはいけませんでした。

実はよく調べたつもりが、この「フレージングコンテンツ」の概念をきちんと理解していなかったんです…。みなさんは同じ失敗をしないように!

2. メニューが特定環境で機能しない

古いiOS(特にiOS 12以前)では特に問題が発生しやすく、クリックイベントが認識されなかったり、見た目が崩れたりしました。

3. スクリーンリーダーが正しく読み上げない

VoiceOverなどのスクリーンリーダーでテストしたとき、構造が不正だとボタンと認識されないケースがありました。アクセシビリティに配慮したサイト制作なのに、肝心なナビゲーションが使えないなんて…💦

✅ 修正した正しいコード(実際に今使っているもの)

多くの人がハンバーガーメニューのトリガーを button タグで作ります。
これは正解です!buttonはクリック操作やアクセシビリティに適しているからです。

<button class="header__nav-toggle" aria-expanded="false" aria-controls="menu" aria-label="メニューを開く">
  <span class="header__nav-toggle-hamburger"></span>
    <span class="header__nav-toggle-hamburger"></span>
    <span class="header__nav-toggle-hamburger"></span>
    <span class="header__nav-toggle-menu">menu</span>
</button>

CSS例(実際のプロジェクトから)

🌟 アクセシビリティ対応のワンランク上のテクニック

前述のコードのaria-expanded属性を使って、JavaScriptでメニュー開閉状態を管理します:

See the Pen Untitled by ひさ (@npupiwfh-the-sans) on CodePen.


📚 button要素の中に入れて良い要素・ダメな要素

HTML仕様によると、ボタン内に配置できるのは「フレージングコンテンツ」のみです:

OKな要素👍

  • <span> – ほとんどの場合はこれを使いましょう
  • <img> – アイコン画像を使う場合
  • <svg> – SVGアイコンを使う場合(私は最近これが多い)
  • <i> – Font Awesomeなどのアイコンフォント用
  • <br> – 改行が必要な場合
  • テキストノード(文字)

NGな要素👎

  • <div> – 👈私が失敗したやつ…
  • <p>
  • <section>
  • <article>
  • <h1><h6>
  • <ul>, <ol>, <li>

💡 実際の現場でのプラスαテクニック

クライアントによって「もうちょっとカッコいいハンバーガーメニューにして」と言われることもあります。

1. SVGアイコンバージョン

最近のプロジェクトでは、spanの代わりにSVGを使うこともありました:

<button class="hamburger-menu" aria-label="メニューを開く">
  <svg width="24" height="24" viewBox="0 0 24 24">
    <path d="M3,6H21V8H3V6M3,11H21V13H3V11M3,16H21V18H3V16Z" />
  </svg>
</button>

✨ さらによくするために:aria属性をつけよう

  • aria-label="メニューを開く"button に追加することで、スクリーンリーダーにも意味が伝わるようになります。

🧩 まとめ:失敗から学んだこと

今回の失敗から学んだ教訓:

  1. HTML仕様をちゃんと理解する:「なんとなく動いてるからいいや」は危険
  2. クロスブラウザテストは必須:特にiOS Safariは要チェック
  3. アクセシビリティを最初から考慮する:後から修正するのは大変

正直、制作現場で「div入れちゃダメなの?」と聞かれたとき、「なんかうまく動かないから」としか説明できなかった自分が恥ずかしかったです。ちゃんと理由を説明できるようになりました!

👇この記事が役に立ったら…

  • ハンバーガーメニューのコード、ぜひ見直してみてください!
  • 初心者さんにぜひ広めてくださいね 😊

🔧 補足:どうしても構造を分けたいときは?

divなどを使いたいなら、buttonの中には入れず、外側で構成することもできます。

<div class="hamburger-wrap" role="button" tabindex="0" aria-label="メニューを開く">
  <div class="bar"></div>
  <div class="bar"></div>
</div>

ただしこの場合は、

  • role="button"tabindex="0" の追加が必要
  • EnterSpace キーでの動作も自作する必要あり

なので、buttonタグを正しく使うのが一番簡単で確実です!

✉️ あなたのリクエスト教えてください!

「この記事わかりやすかった!」
「他にもこんな記事書いてほしい!」
そんな声を、ぜひXのDMで教えてください!😊📩

できるだけリクエストにお応えして、今後の記事作成に活かしていきます

▶️ Xもフォローしてもらえるとめちゃくちゃ嬉しいです!

「私も同じ失敗した」など、ぜひコメントで教えてください!

みんなの知見を集めて、より良いWeb制作を目指しましょう。何か質問があれば、@TumaLOVE0127にDMでも気軽に聞いてくださいね!

実際のコーディングの現場での話、もっと知りたい方はフォローしてもらえると嬉しいです😊

hisa

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA