簡要介紹如何打造回應式且便利的導覽標記元件,讓使用者瀏覽您的網站。
在這篇文章中,我想分享有關導覽標記元件的建構方式。立即試用。
如果您喜歡看影片,請參考這篇文章的 YouTube 版本:
總覽
導覽標記元件會顯示使用者的網站階層位置。這個名稱來自 Hansel 和 Gretel,他會在一些深色樹林中捨棄導覽標記,並回溯追蹤標記來找到回家的路。
本文中的導覽標記不是標準導覽標記,而是類似導覽標記。這些程式庫提供額外功能,可透過 <select>
將同層頁面直接放入導覽中,進而實現多層級存取權。
背景使用者體驗
在上方的元件示範影片中,預留位置類別是電玩遊戲的類型。透過導覽以下路徑即可建立這條小道:home »
rpg » indie » on sale
,如下所示。
這個導覽標記元件應能讓使用者瀏覽這個資訊階層;跳轉分支版本,以及選擇速度與準確度的頁面。
資訊架構
根據收藏和項目,我覺得會相當實用。
集合
集合是一種可供選擇的選項。在本文的導覽標記原型首頁中,系列作品有每秒影格數、角色扮演遊戲、亂鬥、地下城檢索器、體育和拼圖。
項目
電玩遊戲是一種項目,如果代表其他集合,特定集合也可以是某個項目。舉例來說,角色扮演遊戲是一個商品和一個有效的系列。如有某個項目,使用者就會進入該集合頁面。舉例來說,這些遊戲位於 RPG 頁面上,會顯示一系列角色扮演遊戲,包括 AAA、Indie 以及 Self Publish 等其他子類別。
在電腦科學術語中,這個導覽標記元件代表多維度陣列:
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 元素已新增 aria-hidden="true"
。只聽過內容的使用者無法看到圖示,隱藏圖示可以避免出現不必要的雜訊。
分割連結 .crumb
這是傳統導覽標記與元件中其他導覽標記的差異。通常這只是 <a>
連結,但我已透過隱藏的選取方式新增週遊使用者體驗。.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 上。一個屬性可為許多使用者提供按鈕內容。
分隔符裝飾
<span class="crumb-separator" aria-hidden="true">→</span>
您不一定要使用分隔符,只要加入一個分隔符就能正常運作 (請參閱上方影片的第三個範例)。接著我會給每個 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
元件會使用格線,將 SVG 圖示與「幾乎隱藏」的 <select>
元素堆疊在一起。
.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;
}}
}
溢位樣式會設定以下使用者體驗:
- 水平捲動,顯示過度捲動的控制範圍。
- 水平捲動邊框間距。
- 在最後一個鼓棒上,有一個扣針。也就是說,網頁載入時第一個載入標記時,系統會先對齊並進入顯示位置。
- 從 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
首先,無論您在網站或應用程式中使用的路由器類型為何,當使用者變更導覽標記時,網址都必須更新,並向使用者顯示正確的頁面。其次,為了將使用者體驗標準化,請確保當使用者只是瀏覽 <select>
選項時,不會發生非預期的瀏覽。
JavaScript 處理的兩個關鍵使用者體驗措施:Select 已變更,且迫使 <select>
變更事件觸發預防措施。
由於使用 <select>
元素,因此需要使用 Eeger 事件預防功能。在 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 當做網頁元件:示範和程式碼