
JavaScriptなしで動作する、徐々に強化されたモバイル メニューの構築
Last updated on January 21, 2019.
Pure CSS オフキャンバス ハンバーガー メニューは最近の発見というわけではありません。 結局のところ、Chris Coyier は 2012 年の 11 月にこのテクニックについて書きました。
- これがあなたにとって古いトリックであれば、少し付き合ってみてください。 私はクリスの例を改良し、あなたのフィードバックをお待ちしています。 Web の多くはまだ実際に理解していないようなので、仲間がたくさんいます。
以上により、あなた自身のプロジェクトに簡単に組み込めるように、CSS のみを使ってシンプルで反応の良いオフキャンバス ハンバーガー メニューを構築することになります。 しかし、その前に…
JavaScript の何が問題なのか
何もありません。
Aaron Gustafson が、Web 開発における Progressive Enhancements の重要性と JavaScript の役割を私よりもうまく説明しています。 彼の投稿を読むべきです。 しかし、簡潔にするために、要約します。
- 「コア タスクは常に JavaScript なしで達成できる」
- コア タスクは最も安定した層 (JavaScript ではない) で行うべきである。 正しいレイヤーで正しいテクノロジーを採用することです。
- 「JavaScript が実行されない可能性があるため、その可能性を常に考慮しなければならない」
- 潜在ユーザーを無視するのは決して良いアイデアではありません。 それから、より適切なレイヤーで JavaScript に魔法をかけてもらい、既存の UI を改善します。
Step 1: HTML
ご存知のように、最初のステップは常に堅実でよく考えられた HTML のベース レイヤーを書くことです。
注意: 私の例では、アイコンに Font Awesome を使用しています。
Step 1: 純 CSS 反転ハンバーガー メニューの最初の HTML 見たところ、かなり標準的ではないですか? 私たちは
- 親の <header> 要素
- ハンバーガー (“fa-bars”) アイコン
- 主見出し(またはロゴ)
- ナビゲーション <nav>要素
- 閉じるアイコン (“fa-“) 要素内のナビゲーション。close”)ナビゲーションの内側(これについては後で詳しく説明します)
- ナビゲーションの後の “backdrop”。 なぜアンカータグなのか? 後で説明します。
ステップ 2: よりアクセスしやすくしよう
アクセシビリティは決して後付けであってはなりません – アプリケーションを書き上げた後などではいけません。 最初から計画されるべきです。 今、いくつかの基本的な配慮を加えることは、サイトの全体的なアクセシビリティを改善するだけでなく、あなた (開発者) に JavaScript で利用するためのより良いマークアップを提供します。
それを踏まえて、さらにいくつかの属性とスクリーン リーダーのみのテキストを追加します。
ステップ 2: HTML をよりアクセスしやすく改善する これらの属性すべてとそれらの機能を簡単に説明します。
- 私たちは、スクリーン リーダーのために .
- を使用してボタンの情報ラベルを提供し、スクリーン リーダーのために、アイコンは視覚表現であるため , で隠し、<span class=”sr-only”> 要素でスクリーン リーダーのみのテキストを追加しました。
- 私たちは、タブインデックスから「背景」を取り出しました。 それは純粋に視覚的なもので、視覚障害者やキーボードのみのユーザーを混乱させたくありません。
- 私たちは、「背景」の初期状態 (と意味的状態) を設定する amazing 属性を追加しました。 もうゴミはありません。なんとエキサイティングなことでしょう!
ここまでの結果です:

ステップ 3: スタイルを決めよう!
私たちはモバイル ファーストでアプローチするつもりなので、モバイルの「ハンバーガー」表示(興味深い部分)をノックアウトしましょう。
最初に、(インタラクティブ機能なしで)ヘッダーのレイアウトを正しくします。
The result:

Step 4: 純粋な CSS による対話性
CSS でウィジェットを対話的にする場合、いくつかの選択肢があります:
- ラジオまたはチェックボックス
- :target 擬似クラス
Radios と checkbox はタブやモーダル、ドロップダウン、アコーディオンのようにほとんどのウィジェットで非常によく機能します。 Chris Coyier はこのテクニックを “チェックボックス ハック” と名付けました。 Chrome Dev Summit での Paul Lewis のチュートリアルや Luis Manuel のモーフィング ハンバーガー メニューのように、いくつかの開発者はこの「ハック」をオフキャンバス メニューに使用しました。 あなたはそう思わないかもしれませんが、それは全く問題ありません! ターゲット擬似クラスをチェックボックスと交換するのは非常に簡単で、完全に受け入れられるでしょう。
どちらの手法にも注意点があります。
チェックボックスを使用する場合:
- メニュー内のリンクの 1 つが同じページの特定のセクションへのアンカー リンクだった場合、オフキャンバス メニューを閉じるように JavaScript を要求する。
- <input> フィールドがメニューの兄弟であること、または少なくともメニューの祖先の兄弟であることが必要である。 つまり、CSSが少し厄介なのです。 <label> 要素は直接フォーカス可能またはタブ可能ではないので、<label> の可視的な外観を変更しながらチェックボックスのフォーカスを処理するために、少しトリッキーな CSS が必要になります。 チェックボックスの状態変更に影響を与えることは、キーではなく、キーによって行われます。 目の不自由なユーザーは、ウィジェットがチェックボックスによって操作されていることを理解するかもしれませんが、目の見えるキーボード ユーザーは、チェックボックスが明白でないため、混乱するでしょう。 これを避けるために、JavaScript で Event.preventDefault() を実行する必要があります (そして、ページのトップにジャンプすることが潜在的に厄介です)。
そして、私が見逃している他の注意事項があるかもしれません。 いずれにせよ、どの手法を選択するかは好みの問題であり、プロジェクトの要件に左右されます。
クリックしたときの結果:

How all this works
Essentially, the :target pseudo-class gives us a new “state” for styling the targeted navigation. main-menu がターゲットされたとき (そのハッシュが URL に追加されたとき)、メニューをスライド アウトさせることができます。
また、ナビゲーションがターゲットされたときに「背景」を表示できるようにしました。
メイン ハンバーガー アイコンがナビゲーションの ID にリンクされ、閉じるアイコンと背景ボタンの両方がメイン ハンバーガー アイコンにリンクされていることに気付きます。 これにより、閉じるアイコンや背景をクリックすると、ナビゲーションから「フォーカス」、つまり本当の意味での「ターゲット」を取り除くことができます。 背景がリンクでない場合、JavaScript なしではクリックできません。
また、CSS で属性とともに :target セレクタを連結しています。 これは最終的に、クリックしてもヘッダーにジャンプしないように、JavaScript でハンバーガー メニューを徐々に強化する場所となります。 JavaScriptがブラウザのハッシュ動作を乗っ取るということは、:target擬似クラスが機能しなくなることを意味します。 そうなった場合、この属性を利用して、過去にクラスで行ったように true/false 値でトグリングをスタイル化することになります。
しかし、それまでの間、これは JavaScript なしで美しく機能します。 そうでない場合、不格好なブラウザやデバイス (iOS を見ています) は position:absolute となります。
Step 5: 大きな画面のスタイル
Hamburger メニューをモバイル以外のデバイス (または一般に大きな画面) で表示したくないので、そのために必要なメディア クエリを追加しています。
結果:

ほら!
Putting it altogether
Here’s the final HTML:
Here’s the final CSS:
Demo
Try out my CodePen for yourself:
→ Pure CSS Hamburger Menu without JavaScript.Here’s the final CSS:
注意: チェックボックス バージョンのメニューもデモできます。
より洗練されたものにするために JavaScript を追加しますか。
オフキャンバス メニューを完全に CSS で機能させることができますが、そのパフォーマンスと信頼性は改善され、いずれかの手法の欠点を取り巻く対話性を改善するには、何らかの方法で支援する JavaScript が必要になるでしょう。 また、メニューが開いている間、ページのスクロールを防ぐために JavaScript を利用することができます。 しかし、DOM を操作する JavaScript の能力 (フォーカス管理、ARIA 属性の更新など) なしで、強固なレベルのアクセシビリティを提供することは困難です。
JavaScript による Web サイトのアクセシビリティ向上に関する詳細については、以下の記事を参照してください。
- Using ARIA attributes for JavaScript state setting & styling
- Writing JavaScript with mind in accessibility
Have other thoughts or suggestions?
I love you comment with my approach to a pure CSS hamburger menu.
編集とその後の反省
2019年1月21日:記事を編集し、コード例を更新して不要なARIA属性を削除し、アクセシビリティを向上させました。
ARIA の使用と一般的なアクセシビリティのための & テストの開発について学ぶにつれ、いくつかのことに気づきました:
- JavaScript には確かにその場所があり、堅牢なアクセシビリティ UI パターンの一部になる必要があります。
- ARIA ランドマーク以外では、ARIA を適切に使用するには JavaScript が必要です。 そして、私が使用した属性の多くは、マークアップに直接追加するのではなく、一度読み込まれたら JavaScript に追加させた方がよいようなものです。 この概念は、優れたプログレッシブ エンハンスメントの実践に従っています。JavaScript と共に ARIA のステートとプロパティはアップグレードであり、別のレイヤーで処理されるべきものです。 これを修正するために、メニュー CSS に display: none; を追加しました。
そこで、私の Pure CSS Off-Canvas Hamburger Menu の以前のバージョンを実装した場合、このよりシンプルでアクセスしやすいバージョンへの更新を検討してください!
… 続きを読む