パンくずリスト コンポーネントの作成

ユーザーがサイト内を移動できるよう、レスポンシブでアクセスしやすいパンくずリスト コンポーネントを作成する方法について、基本的な概要を示します。

この投稿では、パンくずリスト コンポーネントを作成する方法についての考え方を共有します。 デモをお試しください

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph> デモ

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

概要

パンくずリスト コンポーネントには、 サイト階層でユーザーがどこにいるかを確認しますこの名前はHansel と Gretel は 暗い森の中でパンくずリストを探し 帰り道を見つけることができました トレースできます

この投稿のパンくずリストは標準的なものではありません パンくずリスト パンくずリストのようなものです追加の機能として、兄弟姉妹を <select> を使用して、ページをナビゲーションに直接移動できるため、多層アクセスを実現できます。 考えています

バックグラウンド UX

上記のコンポーネントデモ動画では、プレースホルダ カテゴリは ビデオゲームこのトレイルは、次のようにパス home » rpg » indie » on sale をナビゲートして作成されます。

このパンくずリストコンポーネントを使用すると、 情報階層枝を飛び跳ねたり ページを高速で選択したり 向上します

情報アーキテクチャ

コレクションとアイテムの観点から考えると役に立つと思います。

コレクション

コレクションとは、選択できるオプションの配列です。ホームページから コレクションは FPS、RPG、Brawler ダンジョンクローラー、スポーツ、パズルです。

アイテム

ビデオゲームはアイテムですが、特定のコレクションもアイテムになります。 別のコレクションを表します。たとえば、RPG はアイテムであり、 ありますアイテムの場合は、そのコレクション ページが表示されます。たとえば RPG ページに移動し、RPG ゲームのリスト サブカテゴリーがあります

コンピュータ サイエンスの用語では、このパンくずリスト コンポーネントは、 多次元 配列:

const rawBreadcrumbData = {
  "FPS": {...},
  "RPG": {
    "AAA": {...},
    "indie": {
      "new": {...},
      "on sale": {...},
      "under 5": {...},
    },
    "self published": {...},
  },
  "brawler": {...},
  "dungeon crawler": {...},
  "sports": {...},
  "puzzle": {...},
}

アプリまたはウェブサイトには、カスタム情報アーキテクチャ(IA)があり、 コレクションとランディングという概念が ページと階層トラバーサルはパンくずリストにもなります

レイアウト

マークアップ

適切な HTML を使用することから始めることをおすすめします。次のセクションでは コンポーネント全体に与える影響について 説明します

ダーク&ライトスキーム

<meta name="color-scheme" content="dark light">

上記の color-scheme メタタグ スニペットは、このページがライトモードとダークモードのブラウザを必要としていることをブラウザに通知します あります。サンプルのパンくずリストには、これらのカラーパターンの CSS は含まれていません。 パンくずリストにはブラウザのデフォルトの色が使用されます

<nav class="breadcrumbs" role="navigation"></nav>

インフラストラクチャには、 <nav> 要素 暗黙的な ARIA ロールを持つサイト ナビゲーションに対して できます。 テスト中、role 属性を使用すると、 スクリーン リーダーが要素を操作すると、 今回は追加します

アイコン

ページ上でアイコンが繰り返されている場合、SVG は <use> 要素 path を一度定義すれば、そのインスタンスのすべての アイコンをクリックします。これにより、同じパス情報が繰り返されることがなくなり、 パスの不整合が生じる可能性が低くなります。

この手法を使用するには、非表示の SVG 要素をページに追加し、アイコンをラップします。 一意の ID を持つ <symbol> 要素内:

<svg style="display: none;">

  <symbol id="icon-home">
    <title>A home icon</title>
    <path d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/>
  </symbol>

  <symbol id="icon-dropdown-arrow">
    <title>A down arrow</title>
    <path d="M19 9l-7 7-7-7"/>
  </symbol>

</svg>

ブラウザは SVG HTML を読み取り、アイコン情報をメモリに挿入します。 残りのページでは ID を使用して、リソースの追加や アイコンをこのように変更します。

<svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
  <use href="#icon-home" />
</svg>

<svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
  <use href="#icon-dropdown-arrow" />
</svg>

レンダリングされた SVG use 要素を表示している DevTools。

ページ パフォーマンスへの影響を最小限に抑えながら、一度定義して何度でも使用できる 柔軟性のあるスタイル設定ですSVG 要素に aria-hidden="true" が追加されています。 閲覧しているコンテンツを音声しか聞こえないだけの場合、アイコンは役に立ちません。 不要なノイズの追加を防ぐことができます。

ここで、従来のパンくずリストとこのコンポーネントのパンくずリストが分かれています。 通常、これは <a> リンクのみですが、 表示されます。.crumb クラスは、リンクをレイアウトし、 一方、.crumbicon はアイコンの積み重ねと選択を行います。 できます。スプリットリンクというのは Split-button に似ており、 ページナビゲーションはおすすめです

<span class="crumb">
  <a href="#sub-collection-b">Category B</a>
  <span class="crumbicon">
    <svg>...</svg>
    <select class="disguised-select" title="Navigate to another category">
      <option>Category A</option>
      <option selected>Category B</option>
      <option>Category C</option>
    </select>
  </span>
</span>

リンクと一部のオプションは特別なものではありませんが、 作成します。<select> 要素に title を追加すると、画面に役立ちます。 ボタンの操作に関する情報を提供します。ただし、 どのユーザーでも同じように利用できます iPad。1 つの属性で多くのユーザーにボタンのコンテキストを提供します。

非表示の選択要素にカーソルを合わせた状態と、その状態を示すスクリーンショット
コンテキスト ツールチップが表示されています。

区切りの装飾

<span class="crumb-separator" aria-hidden="true">→</span>

区切り文字は任意で、1 つだけ追加してもかまいません(動画の 3 番目の例を参照)。 を参照)。次に、それぞれの aria-hidden="true" は装飾的であり、 読み上げる内容を指定できます

次に説明する gap プロパティは、これらの間隔を簡単に行えるようにします。

スタイル

この色はシステムカラーを使用しているため、ほとんどの場合、スタイルのギャップやスタックです。

レイアウト方向とフロー

Flexbox オーバーレイとともにパンくずリスト ナビゲーションの配置を示す DevTools
機能。

プライマリ ナビゲーション要素 nav.breadcrumbs で、スコープ カスタム プロパティを設定しています そうでない場合は、水平方向に配置されます。 できます。これにより、パンくず、分割線、アイコンが確実に配置されます。

.breadcrumbs {
  --nav-gap: 2ch;

  display: flex;
  align-items: center;
  gap: var(--nav-gap);
  padding: calc(var(--nav-gap) / 2);
}

Flexbox オーバーレイと縦に並んだ 1 つのパンくずリスト。

.crumb は、いくつかのオプションを使用して、水平方向に垂直方向に配置されたレイアウトを確立します。 リンクの子を対象にしてスタイルを指定します。 white-space: nowrap。これは複数単語のパンくずリストで重要ですが、 複数行に配置する必要があります後ほど、スタイルを追加して この white-space プロパティによって水平方向にオーバーフローします。

.crumb {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--nav-gap) / 4);

  & > a {
    white-space: nowrap;

    &[aria-current="page"] {
      font-weight: bold;
    }
  }
}

aria-current="page" が追加され、現在のページリンクが あります。スクリーン リーダーのユーザーは、リンクが 視覚に訴えるユーザーがアクセスしやすいように、 同様のユーザーエクスペリエンスが得られます

.crumbicon コンポーネントは、グリッドを使用して「ほぼ同じ」の SVG アイコンを積み重ねています。 invisible"<select> 要素。

行と列の両方が配置されているボタンの上に重ねて表示されている、グリッド DevTools
作成します。

.crumbicon {
  --crumbicon-size: 3ch;

  display: grid;
  grid: [stack] var(--crumbicon-size) / [stack] var(--crumbicon-size);
  place-items: center;

  & > * {
    grid-area: stack;
  }
}

<select> 要素は DOM の最後にあるため、スタックの一番上にあります。 インタラクティブです要素を引き続き使用できるように、opacity: .01 のスタイルを追加します。 アイコンの形状にぴったりフィットする選択ボックスが作成されます。 これは、<select> 要素の外観をカスタマイズするのに便利な方法ですが、 組み込みの機能は維持できます

.disguised-select {
  inline-size: 100%;
  block-size: 100%;
  opacity: .01;
  font-size: min(100%, 16px); /* Defaults to 16px; fixes iOS zoom */
}

オーバーフロー

パンくずリストは、長い道のりを表すことができます。Google Cloud の 必要に応じて画面外に 移動させることもできますが パンくずリストコンポーネントは適切に評価されています

.breadcrumbs {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-padding-inline: calc(var(--nav-gap) / 2);

  & > .crumb:last-of-type {
    scroll-snap-align: end;
  }

  @supports (-webkit-hyphens:none) { & {
    scroll-snap-type: none;
  }}
}

オーバーフロー スタイルにより、以下の UX が設定されます。

  • 水平スクロール(オーバースクロールの封じ込めあり)。
  • 水平スクロールのパディング。
  • 最後のパンくずにスナップ ポイントを 1 つ。つまりページの読み込み時に クラム読み込みがスナップされて表示されている。
  • 横向き表示に苦労していた Safari からスナップ ポイントを削除 スクロールとスナップ エフェクトの組み合わせ。

メディアクエリ

ビューポートを小さくするために [Home] の非表示をラベル、 アイコンのみ:

@media (width <= 480px) {
  .breadcrumbs .home-label {
    display: none;
  }
}

ホームラベルがある場合とない場合のパンくずリストを並べて表示し、
あります

ユーザー補助

モーション

このコンポーネントではそれほど大きな動きはありませんが、 prefers-reduced-motion チェックで遷移を実行することで、不要な動きを防ぐことができます。

@media (prefers-reduced-motion: no-preference) {
  .crumbicon {
    transition: box-shadow .2s ease;
  }
}

他に変更が必要なスタイルはありません。ホバー効果やフォーカス効果が優れている transition がなくても意味がありますが、モーションに問題がなければ、微妙な できます。

JavaScript

まず、サイトやアプリで使用しているルーターの種類にかかわらず、 ユーザーがパンくずリストを変更した場合は、URL を更新し、ユーザーが 適切なページが表示される。次に、ユーザー エクスペリエンスを正規化するために、 ユーザーが <select> をブラウジングしているときに予期せぬナビゲーションが発生することはありません 。

JavaScript で処理する 2 つの重要なユーザー エクスペリエンス対策、select has 変更イベント起動防止 <select> の変更を積極的に実行。

<select> を使用しているため、積極的なイベントの防止が必要です。 要素です。Windows Edge では、おそらく他のブラウザでも changed を選択します。 イベントは、ユーザーがキーボードでオプションをブラウジングすると発生します。だからこそ ユーザーがオプションを疑似選択しただけなので、 enter または click での選択をまだ確認していません。意欲的な イベントにより、このコンポーネント カテゴリ変更機能にはアクセスできなくなります。その理由は、 選択ボックスを開いてアイテムを閲覧すると、イベントが発生し、 ユーザーが閲覧できるようになる前にページを変更します。

<select> の変更されたイベントが改善されました

const crumbs = document.querySelectorAll('.breadcrumbs select')
const allowedKeys = new Set(['Tab', 'Enter', ' '])
const preventedKeys = new Set(['ArrowUp', 'ArrowDown'])

// watch crumbs for changes,
// ensures it's a full value change, not a user exploring options via keyboard
crumbs.forEach(nav => {
  let ignoreChange = false

  nav.addEventListener('change', e => {
    if (ignoreChange) return
    // it's actually changed!
  })

  nav.addEventListener('keydown', ({ key }) => {
    if (preventedKeys.has(key))
      ignoreChange = true
    else if (allowedKeys.has(key))
      ignoreChange = false
  })
})

そのための戦略として、各 <select> でキーボードダウン イベントを監視します。 要素を検証し、押されたキーがナビゲーション確認(Tab または Enter)または空間ナビゲーション(ArrowUp または ArrowDown)。こちらの 通知のイベントがいつ終了したかを <select> 要素が起動します。

まとめ

どのようにやり方をしたかわかったので、どのように感じますか? ‽ 🙂?

アプローチを多様化して、ウェブで構築するすべての方法を学びましょう。 デモを作成し、ツイートしてリンクを送ってください 下の [コミュニティリミックス]セクションに アクセスしてください

コミュニティ リミックス