サイド ナビゲーション コンポーネントの作成

レスポンシブ スライドアウト サイドナビゲーションの基本的な作成方法

今回の投稿では、私がこのウェブ用 Sidenav コンポーネントをプロトタイピングし、 レスポンシブ、ステートフル、キーボード ナビゲーションをサポートし、JavaScript の有無にかかわらず動作します。 ブラウザをまたいで動作します。デモをお試しください。

動画で視聴したい場合は、この投稿の YouTube バージョンをご利用ください。

概要

レスポンシブ ナビゲーション システムを構築するのは簡単ではありません。キーボードを使うユーザーもいれば 高性能なパソコンを使用している人もいれば、小型のモバイル デバイスからアクセスする人もいます。 アクセスするユーザー全員がメニューを開閉できる必要があります。

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">をご覧ください。 <ph type="x-smartling-placeholder">
</ph> パソコンからモバイルへのレスポンシブ レイアウトのデモ
<ph type="x-smartling-placeholder">をご覧ください。 <ph type="x-smartling-placeholder">
</ph> iOS と Android でライトモードとダークモードをオフにする

ウェブ戦術

このコンポーネントの探索では、いくつかの重要なウェブ プラットフォーム機能を組み合わせることができました。

  1. CSS :target
  2. CSS グリッド
  3. CSS 変換
  4. ビューポートとユーザー設定の CSS メディアクエリ
  5. focus 用 JS UX の機能強化

私のソリューションにはサイドバーが 1 つあり、「モバイル」のときだけ切り替えられる540px 以下のビューポート。 540px は、モバイルのインタラクティブ レイアウトと静的なデスクトップ レイアウトを切り替えるためのブレークポイントです。

CSS :target 疑似クラス

一方の <a> リンクは URL ハッシュを #sidenav-open に設定し、もう一方は空('')に設定します。 最後に、要素にはハッシュに一致する id があります。

<a href="#sidenav-open" id="sidenav-button" title="Open Menu" aria-label="Open Menu">

<a href="#" id="sidenav-close" title="Close Menu" aria-label="Close Menu"></a>

<aside id="sidenav-open">
  …
</aside>

これらの各リンクをクリックすると、ページの URL のハッシュ状態が変更されます。 次に、疑似クラスを使用して、sidenav を表示および非表示にします。

@media (max-width: 540px) {
  #sidenav-open {
    visibility: hidden;
  }

  #sidenav-open:target {
    visibility: visible;
  }
}

CSS グリッド

これまでは絶対位置か固定位置のみを使用していました。 サイドナビゲーションのレイアウトとコンポーネントです。ただし、グリッドは grid-area 構文を使用し、 を使用すると、複数の要素を同じ行または列に割り当てることができます。

スタック

プライマリ レイアウト要素 #sidenav-container は、1 行と 2 列を作成するグリッドです。 それぞれに 1 つずつ stack という名前が付けられています。スペースに制約がある場合は、CSS によって、<main> 要素のすべての要素が すべての要素を同じスペースに配置して、スタックを作成します。

#sidenav-container {
  display: grid;
  grid: [stack] 1fr / min-content [stack] 1fr;
  min-height: 100vh;
}

@media (max-width: 540px) {
  #sidenav-container > * {
    grid-area: stack;
  }
}

<aside> は、サイド ナビゲーションを含むアニメーション要素です。機能 2 つの子: [nav] という名前のナビゲーション コンテナ <nav> と背景 <a> [escape] という名前の、メニューを閉じます。

#sidenav-open {
  display: grid;
  grid-template-columns: [nav] 2fr [escape] 1fr;
}

2fr1fr を使用して、メニュー オーバーレイとネガティブ スペースの閉じるボタンの最適な比率を見つけます。

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">をご覧ください。 <ph type="x-smartling-placeholder">
</ph> 比率を変更したときにどうなるかを示すデモ。

CSS の 3D 変換と切り替え効果

レイアウトがモバイルのビューポート サイズで積み重ねられました。新しいスタイルを追加するまで デフォルトで記事の上に重ねて表示されます次のセクションで狙う UX は次のとおりです。

  • 開閉をアニメーション化する
  • ユーザーが納得できる場合にのみ、動きのあるアニメーションにします。
  • キーボード フォーカスが画面外の要素に入らないように visibility をアニメーション化する

モーション アニメーションを実装するにあたり、まずはユーザー補助を念頭に置いてください。

アクセシブルなモーション

誰もがスライドアウト モーションを望んでいるわけではありません。ソリューションでは を適用するには、メディアクエリ内の CSS 変数 --duration を調整します。このメディアクエリ値は オペレーティング システムでのモーションに関する設定(利用可能な場合)。

#sidenav-open {
  --duration: .6s;
}

@media (prefers-reduced-motion: reduce) {
  #sidenav-open {
    --duration: 1ms;
  }
}
<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
期間を適用した場合と適用しない場合のインタラクションのデモ

サイドナビゲーションをスライドさせて開閉するときに 要素を即座にビューに移動し、動きのない状態を維持します。

遷移、変換、翻訳

サイド ナビゲーション(デフォルト)

モバイルのサイド ナビゲーションのデフォルト状態をオフスクリーン状態に設定するには、 transform: translateX(-110vw) で要素を配置します。

-100vw の一般的なオフスクリーン コードに、別の 10vw を追加しました。 これにより、sidenav の box-shadow が非表示のときにメイン ビューポートをのぞかせているようになりました。

@media (max-width: 540px) {
  #sidenav-open {
    visibility: hidden;
    transform: translateX(-110vw);
    will-change: transform;
    transition:
      transform var(--duration) var(--easeOutExpo),
      visibility 0s linear var(--duration);
  }
}
サイド ナビゲーション

#sidenav 要素が :target と一致した場合は、translateX() の位置をホームベースの 0 に設定します。 CSS が要素を -110vw 以外の位置から「イン」にスライドするのを待ちます。 URL ハッシュが変更されたときの var(--duration) に対する 0 の位置。

@media (max-width: 540px) {
  #sidenav-open:target {
    visibility: visible;
    transform: translateX(0);
    transition:
      transform var(--duration) var(--easeOutExpo);
  }
}

切り替え効果の表示

目標はスクリーンリーダーの メニューを非表示にすることです オフスクリーン メニューにフォーカスが移動しません。それには、ファイアウォール ルールで :target が変更されたときの可視性の遷移。

  • 最初は表示を移行しないでください。要素がスライドインして フォーカスが当たるのを確認できます
  • 外出時は表示を遷移しますが、遅らせることで、遷移終了時に hidden に切り替わります。

ユーザー補助機能の UX の強化

このソリューションでは、状態を管理できるように URL を変更する必要があります。 当然、ここでは <a> 要素を使用する必要があります。これにより、優れたユーザー補助機能が実現します。 無料で提供されています。意図を明確に示すラベルでインタラクティブな要素を装飾しましょう。

<a href="#" id="sidenav-close" title="Close Menu" aria-label="Close Menu"></a>

<a href="#sidenav-open" id="sidenav-button" class="hamburger" title="Open Menu" aria-label="Open Menu">
  <svg>...</svg>
</a>
<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
ナレーションとキーボード操作の UX のデモ。

これで、マウスとキーボードの両方について、主要な操作ボタンの目的が明確に示されるようになりました。

:is(:hover, :focus)

この便利な CSS 関数疑似セレクタを使用すると、 マウスオーバースタイルでも フォーカスを共有できます

.hamburger:is(:hover, :focus) svg > line {
  stroke: hsl(var(--brandHSL));
}

JavaScript にスプリンクルを追加する

閉じるには escape を押します

キーボードの Escape キーを押すとメニューが閉じますか?つなぎます

const sidenav = document.querySelector('#sidenav-open');

sidenav.addEventListener('keyup', event => {
  if (event.code === 'Escape') document.location.hash = '';
});
ブラウザの履歴

開閉操作が複数のコンテナに重なってしまわないように、 次の JavaScript をインラインで追加します。 閉じるボタンがあります。

<a href="#" id="sidenav-close" title="Close Menu" aria-label="Close Menu" onchange="history.go(-1)"></a>

これにより、閉じるときに URL 履歴エントリが削除され、メニューが 表示されます。

UX を重視

次のスニペットは、変更後に [開く] ボタンと [閉じる] ボタンにフォーカスするためです。 開閉します。簡単に切り替えられるようにしたい。

sidenav.addEventListener('transitionend', e => {
  const isOpen = document.location.hash === '#sidenav-open';

  isOpen
      ? document.querySelector('#sidenav-close').focus()
      : document.querySelector('#sidenav-button').focus();
})

サイド ナビゲーションが開いたら、閉じるボタンをフォーカスします。サイドナビゲーションが閉じると 「開く」ボタンをフォーカスします。これを行うには、JavaScript の要素で focus() を呼び出します。

まとめ

私のやり方わかったな、どうやって?!これで、コンポーネント アーキテクチャが面白いものになります。 スロット付きの最初のバージョンは誰が制作するのでしょうか。🙂

多様なデータで さまざまなアプローチを学び、ウェブで構築するあらゆる方法を学べます。Glitch を作成します。 あなたのバージョンをツイートしていただければ、 以下のコミュニティ リミックスのセクションをご覧ください。

コミュニティ リミックス