✅ 【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に追加することで、スクリーンリーダーにも意味が伝わるようになります。
🧩 まとめ:失敗から学んだこと
今回の失敗から学んだ教訓:
- HTML仕様をちゃんと理解する:「なんとなく動いてるからいいや」は危険
- クロスブラウザテストは必須:特にiOS Safariは要チェック
- アクセシビリティを最初から考慮する:後から修正するのは大変
正直、制作現場で「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"の追加が必要EnterやSpaceキーでの動作も自作する必要あり
なので、buttonタグを正しく使うのが一番簡単で確実です!
✉️ あなたのリクエスト教えてください!
「この記事わかりやすかった!」
「他にもこんな記事書いてほしい!」
そんな声を、ぜひXのDMで教えてください!😊📩
できるだけリクエストにお応えして、今後の記事作成に活かしていきます!
▶️ Xもフォローしてもらえるとめちゃくちゃ嬉しいです!
「私も同じ失敗した」など、ぜひコメントで教えてください!
みんなの知見を集めて、より良いWeb制作を目指しましょう。何か質問があれば、@TumaLOVE0127にDMでも気軽に聞いてくださいね!
実際のコーディングの現場での話、もっと知りたい方はフォローしてもらえると嬉しいです😊
コメントを残す