ユーザーがサイト内を移動できるよう、レスポンシブでアクセスしやすいパンくずリスト コンポーネントを作成する方法について、基本的な概要を示します。
この記事では、パンくずリスト コンポーネントを作成する方法について考えたいと思います。デモを試す
動画で確認したい場合は、YouTube 版の投稿をご覧ください。
概要
パンくずリスト コンポーネントには、 サイト階層でユーザーがどこにいるかを確認しますこの名前はHansel と Gretel は 暗い森の中でパンくずリストを探し 帰り道を見つけることができました トレースできます
この記事のパンくずリストは標準のパンくずリストではなく、パンくずリストに似ています。追加の機能として、兄弟姉妹を
<select>
を使用して、ページをナビゲーションに直接移動できるため、多層アクセスを実現できます。
考えています
バックグラウンド UX
上記のコンポーネントデモ動画では、プレースホルダ カテゴリは
ビデオゲームこのトレイルは、以下に示すように、home »
rpg » indie » on sale
というパスに移動することで作成されます。
このパンくずリスト コンポーネントにより、ユーザーは情報階層を移動し、枝を飛び越えてページをすばやく正確に選択できるようになります。
情報アーキテクチャ
コレクションとアイテムの観点で考えるとわかりやすいでしょう。
コレクション
コレクションとは、選択できるオプションの配列です。ホームページから コレクションは FPS、RPG、Brawler ダンジョンクローラー、スポーツ、パズルです。
アイテム
ビデオゲームはアイテムですが、特定のコレクションもアイテムになります。 別のコレクションを表します。たとえば、RPG はアイテムであり、有効なコレクションです。アイテムの場合は、ユーザーがそのコレクション ページにいます。たとえば、RPG ページには、AAA、インディー、セルフパブリッシュなどのサブカテゴリを含む 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>
サイト ナビゲーションには、暗黙的な ARIA ロール「navigation」を持つ <nav>
要素を使用するのが適切です。テストで、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 要素に aria-hidden="true"
が追加されています。
ブラウジングしている人がコンテンツを聞いているだけの場合、アイコンは役に立ちません。
不要なノイズの追加を防ぐことができます。
分割リンク .crumb
従来のパンくずリストとこのコンポーネントのパンくずリストの違いは、この点にあります。通常、これは <a>
リンクのみですが、偽装された選択を使用して移動 UX を追加しました。.crumb
クラスは、リンクをレイアウトし、
一方、.crumbicon
はアイコンの積み重ねと選択を行います。
できます。ページ ナビゲーション用の分割ボタンに非常によく似ているため、分割リンクと呼んでいます。
<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
プロパティを使用すると、これらの間隔を簡単に設定できます。
スタイル
この色はシステムカラーを使用しているため、そのほとんどがスタイルのギャップやスタックです。
レイアウトの向きと流れ
プライマリ ナビゲーション要素 nav.breadcrumbs
は、子が使用するスコープ付きカスタム プロパティを設定します。設定しない場合、水平方向に垂直に配置されたレイアウトが確立されます。これにより、パンくずリスト、区切り線、アイコンが揃います。
.breadcrumbs {
--nav-gap: 2ch;
display: flex;
align-items: center;
gap: var(--nav-gap);
padding: calc(var(--nav-gap) / 2);
}
各 .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
コンポーネントは、グリッドを使用して「ほぼ見えない」<select>
要素で SVG アイコンを積み重ねます。
.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 */
}
オーバーフロー
パンくずリストは非常に長い経路を表す必要があります。必要に応じて、横方向に画面外に移動できるものを許可するのが好きです。このパンくずリスト コンポーネントは、その条件を満たしていると感じました。
.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 からスナップ ポイントを削除 スクロールとスナップ エフェクトの組み合わせ。
メディアクエリ
小さいビューポート向けの微妙な調整として、[ホーム] ラベルを非表示にしてアイコンのみを表示することもできます。
@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 を更新し、適切なページをユーザーに表示する必要があります。2 つ目は、ユーザー エクスペリエンスを標準化するために、ユーザーが <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>
要素が起動します。
まとめ
どのようにやり方をしたかわかったので、どのように感じますか? ‽ 🙂?
アプローチを多様化して、ウェブで構築するすべての方法を学びましょう。 デモを作成し、ツイートしてリンクを送ってください 下の [コミュニティリミックス]セクションに アクセスしてください
コミュニティ リミックス
- ウェブ コンポーネントとしての Tux Solbakk: デモとコード