
使用 HTML 清單構建導覽選單與目錄
在 HTML5 時代,我們常用清單元素來組織導覽鏈結。例如,一組導覽連結本質上就是一個清單,因此使用 <ul> 配合 <li> 來標記主選單項目是再自然不過的事情。瀏覽器與輔助技術也能藉由清單的結構,更清楚地理解這些連結的群組關係。事實上,當使用螢幕閱讀器瀏覽時,它會宣告「包含 X 個項目的清單」,提示使用者此處有一組導覽連結。換言之,清單不僅在視覺上構造選單,在語意上也提供了額外資訊。
無序清單與有序清單的選單應用
無序清單 <ul> 通常用於導覽選單中列出沒有特定順序的項目。例如網站的主選單(首頁、關於我們、聯絡方式等)使用 <ul> 來列出各個頁面的連結最為恰當。相對地,有序清單 <ol> 則表示項目有先後次序;在導覽中較少見,但在某些情境可能派上用場,例如Breadcrumb麵包屑導覽或步驟流程。當內容順序很重要時(例如步驟指南或章節目錄),應使用 <ol>;若順序無關緊要, <ul> 則足夠勝任。判斷的方法是:將項目順序對調,語意是否改變?若改變,就用 <ol>,否則用 <ul> 即可。一般網站主選單的各個頁面並沒有先後之分,因此大多採用無序清單。
範例:基本導覽選單結構(使用 <nav> 搭配清單標記):
<!-- 導覽區塊開始 -->
<nav class="main-menu">
<ul>
<li><a href="/">首頁</a></li>
<li><a href="/about">關於我們</a></li>
<li><a href="/products">產品</a></li>
<li><a href="/contact">聯絡我們</a></li>
</ul>
</nav>
<!-- 導覽區塊結束 -->
上例中,我們以 <nav> 元素作為容器(代表頁面的導航區段),內含一個 <ul> 清單列出導覽連結。每個連結置於 <li> 清單項中,使結構清晰易讀。你可以想像,這樣的標記可以透過 CSS 呈現為垂直的側邊欄選單、橫向的導覽列,甚至是下拉選單—all 取決於你如何設計樣式。此外,若日後需要增加子選單(例如在「產品」下列出不同產品分類),也只需在對應的 <li> 裡嵌套另一個 <ul> 清單即可,HTML 本身允許清單無限深度巢狀。利用巢狀的 <ul> 清單代表子選單項,是構建階層式選單的常見做法。
值得一提的是,也有人問:「一定要在 <nav> 中使用 <ul> 嗎?不能直接放一堆 <a> 嗎?」 理論上,你可以直接將多個 <a> 置於 <nav> 下,結構上仍屬有效HTML。然而,將導覽連結包裝在清單中帶來了較佳的語義和可塑性:除了如前述提供群組語意,清單也方便我們以 CSS 控制版面(例如設定整組間距、對齊方式等)。綜合考量,「在 <nav> 中使用清單來標記導覽項目」已成為業界良好風格。這種結構清晰又利於維護的方式,讓導覽選單的HTML更具邏輯性和可讀性。
定義清單在目錄設計中的運用
除了無序和有序清單,HTML 的 定義清單 <dl> 也有其獨特用途。<dl> 不是用來列出並排的選單項目,而是表示名詞 - 定義的配對列表。典型應用包括詞彙表(Glossary)或內容摘要等。例如,你可以用 <dl> 列出網站各個部分的名稱及說明,或用於 FAQ 的問題與答案列表。由於 <dl> 天生適合呈現「名稱:說明」這種目錄式資訊,我們可以在需要給予項目額外描述時採用它。例如一個「文件目錄」頁面,列出章節標題並附加簡短描述,就很適合用 <dt> 表示章節標題、<dd> 表示該章節介紹。
範例:使用 <dl> 製作內容目錄/索引:
<h2>網站目錄</h2>
<dl>
<dt><a href="/docs/html-basics">HTML 基礎教程</a></dt>
<dd>介紹 HTML 基本語法與元素的入門指南。</dd>
<dt><a href="/docs/css-guide">CSS 設計指南</a></dt>
<dd>涵蓋 CSS 排版、樣式和響應式設計的完整說明。</dd>
<dt><a href="/docs/js-intro">JavaScript 新手入門</a></dt>
<dd>教你如何在網頁中加入互動效果的 JavaScript 語言課程。</dd>
</dl>
上述片段將「教程名稱」作為 <dt>(定義項目名稱),而其說明文字置於 <dd>(定義項目描述)中。整組內容被 <dl> 包裹,表示一系列名稱與說明的列表。這種結構對於內容目錄(目錄頁)或術語列表特別有用:使用者能同時看到項目及其說明,一目了然。需要注意的是,<dl> 並不適合作為主導覽菜單,因為導覽選單通常沒有每個連結對應的描述;<dl> 更適合在需要展示附加資訊的目錄情境中使用。
綜上所述,HTML 清單元素提供了靈活的架構來構建導覽和目錄。<ul>/<ol> 定義了鏈結列表,可直觀地表現選單項目;<dl> 定義了名詞解釋列表,適合內容索引或資料條目的展示。下一步,我們將探討讓這些清單式選單在各種裝置上都能友善呈現的方法,也就是響應式設計的考量。
響應式清單導覽設計考量
現代網站需面對各種尺寸的螢幕—from 大尺寸桌機顯示器到手機小螢幕—導覽選單也必須隨之調整,確保良好的使用體驗。傳統上,桌面版網站的導覽列可能橫向展開所有選項,但在行動裝置上,空間有限,如果不做優化,清單式選單可能會變得擁擠難讀,甚至超出版面。為了解決這個問題,我們需要對清單導覽實施響應式設計,根據螢幕大小改變選單的呈現方式。
一個常見的策略是:在窄螢幕上隱藏部分或全部導覽連結,僅保留一個「選單」按鈕圖示(俗稱漢堡選單),點擊後再顯示完整清單。透過 CSS 媒體查詢,我們可以設定:當螢幕寬度低於某個閾值時,將導覽列中的連結隱藏,只顯示代表展開選單的圖示;同時調整選單展開時的佈局,例如改為垂直堆疊顯示項目,以適應手機縱向屏幕。以下是一個簡化的實作範例:
範例:響應式選單的 HTML 與 CSS
<!-- 響應式選單按鈕(僅在小螢幕顯示) -->
<button class="menu-toggle" aria-label="切換選單">☰ 選單</button>
<!-- 導覽選單 -->
<nav class="site-nav" id="mainNav">
<ul>
<li><a href="/">首頁</a></li>
<li><a href="/about">關於我們</a></li>
<li><a href="/products">產品</a></li>
<li><a href="/contact">聯絡我們</a></li>
</ul>
</nav>
/* 基本導覽列樣式 */
.site-nav ul {
list-style: none;
margin: 0; padding: 0;
background-color: #333;
}
.site-nav li { display: inline-block; }
.site-nav a {
display: inline-block;
color: #fff;
text-decoration: none;
padding: 10px 15px;
}
/* 漢堡選單按鈕:大螢幕預設隱藏 */
.menu-toggle { display: none; background: #333; color: #fff; padding: 10px 15px; border: none; }
/* 小螢幕時的調整 */
@media (max-width: 600px) {
.site-nav ul {
display: none; /* 隱藏清單項目 */
flex-direction: column; /* (若使用 Flexbox 可垂直排列) */
}
.menu-toggle { display: block; } /* 顯示漢堡選單按鈕 */
}
/* 當.nav開啟時顯示清單(透過切換類別) */
.site-nav.open ul {
display: flex; /* 小螢幕時以彈性布局垂直顯示 */
}
在上述程式碼中,我們利用了一個隱藏的按鈕 .menu-toggle 來切換選單顯示。CSS 部分的媒體查詢定義了當螢幕寬度小於600px時:隱藏導覽列的清單項目,只顯示按鈕。@media (max-width: 600px) 區塊將 .site-nav ul 設為 display: none,而把 .menu-toggle 顯示出來。如此一來,在手機上使用者只會看到一個「☰ 選單」按鈕。
接下來,為了讓按鈕點擊能真正切換選單,需要一些簡單的JavaScript來增減 .open 類別:當 .site-nav 有 .open 類別時,其內嵌的清單用 display: flex 顯示出來,垂直列出連結項目。以下是對應的 JavaScript:
<script>
const menuBtn = document.querySelector('.menu-toggle');
const nav = document.querySelector('.site-nav');
menuBtn.addEventListener('click', () => {
nav.classList.toggle('open');
});
</script>
(在此我們為簡潔直接將腳本寫在HTML中,實務上可獨立為.js文件。)
當使用者點擊「選單」按鈕時,<nav> 會切換加入或移除 .open 類別,觸發CSS顯示或隱藏清單。如此,即實現了一個基本的響應式選單:大螢幕時橫向展開所有連結,小螢幕時收合為漢堡按鈕點擊展開。
響應式設計重點提示:
切記要隱藏的不只是視覺上,還包括對輔助工具的隱藏。上例中使用 CSS display: none 隱藏選單時,螢幕閱讀器也不會讀出其中內容,確保收合時不造成干擾。
選單展開/收合的按鈕應該提供適當的線索,例如用漢堡圖示並加上 aria-label(如上例的 aria-label="切換選單")讓視障者知道按鈕功能。
可以使用 CSS 過渡效果或動畫讓選單展開更順暢,用戶體驗更佳(此部分可自行延伸實作)。
透過響應式技巧,我們的清單導覽可以在各尺寸裝置上保持可用性和美觀性。接下來,讓我們進一步探討導覽選單的無障礙設計,確保我們的選單對所有用戶(包括障礙者)都友善可及。
無障礙導覽設計與 ARIA 技巧
在設計導覽選單與目錄時,無障礙(Accessibility)考量至關重要。這包含確保鍵盤可導航、螢幕閱讀器能正確解讀,以及使用適當的 ARIA 屬性提供額外輔助資訊。我們將介紹幾個關鍵要點和實作技巧:
使用語意標記與 Landmarks
首先,盡量利用 HTML5 語意標籤,比如前述的 <nav> 元素來包覆導覽區域。瀏覽器和輔助技術會將 <nav> 認知為導航區塊(landmark),方便使用者快速跳轉。如果頁面上有多個 <nav>(例如主選單、頁內目錄等),可以透過 aria-label 或 aria-labelledby 為每個 <nav> 加上描述,區分不同用途的導覽區。例如:
<nav aria-label="主選單"> ... </nav>
<nav aria-label="頁面目錄"> ... </nav>
如上,為主要網站選單和頁面內目錄分別添加 aria-label,讓螢幕閱讀器在切換區塊時能讀出「主選單」、「頁面目錄」等提示。這對使用者理解當前導航內容大有幫助。
如果因特殊原因無法使用 <nav>,至少應在容器上加上 role="navigation" 來表明其導航角色。不過既然 <nav> 已被廣泛支援並語意明確,建議優先使用 <nav> 元素而非手動設定 role。
ARIA 屬性:aria-current 標示當前頁
在導覽連結中,標示目前所在頁面可以提升可及性。方法是使用 ARIA 提供的 aria-current 屬性。將當前頁面的對應 <a> 標籤加上 aria-current="page",螢幕閱讀器在讀到此連結時會額外提示「目前頁面」的訊息。這避免了視障使用者誤點擊已經所在的頁面連結,造成不必要的重新載入。
例如,如果使用者目前位於「首頁」,則首頁的連結標記可寫成:
<li><a href="/" aria-current="page">首頁</a></li>
而其它頁面的連結不應包含 aria-current。這個屬性對應到各種情境還有不同值(如 step、location 等),但對於網頁導覽而言,page 是最常用且適當的值。實作上非常簡單,但對體驗影響重大:使用輔助技術的用戶將清楚知道哪個選單項是當前頁。
ARIA 屬性:aria-haspopup 和 aria-expanded(下拉選單)
如果你的導覽選單包含下拉選單(子選單)或需要點擊展開的選單項目,那就涉及 ARIA 的下拉相關屬性。當一個選單項有子選單時,應:
在觸發展開的元素上加上 aria-haspopup="true",表示「這個元素會彈出一個子選單」。通常我們會將主選單項設計為一個按鈕或可點擊的 <a>,附帶 aria-haspopup 即可。輔助技術將據此提示使用者此項目可展開子選單。
同時使用 aria-expanded 指示目前子選單的展開狀態:aria-expanded="false" 意味著子選單目前隱藏,true 則表示目前已展開。當使用者點擊展開或收合時,記得用 JavaScript 切換此值,同步更新狀態。螢幕閱讀器會在元素聚焦時讀出「已折疊」或「已展開」等提示。
此外,aria-controls="submenu-id" 也很有用,它建立一個從觸發元素指向子選單容器的關聯。比如按鈕有一個 ID 為 submenu 的 <ul> 子清單,則按鈕標記 <button aria-haspopup="true" aria-expanded="false" aria-controls="submenu">產品列表</button>。這樣輔助技術能理解按鈕控制的對象是什麼。
範例:帶下拉子選單的導覽項目(ARIA 標記):
<li>
<!-- 可點擊的主選單按鈕 -->
<button aria-haspopup="true" aria-expanded="false" aria-controls="prod-menu">
產品分類 ▼
</button>
<!-- 子選單 -->
<ul id="prod-menu" class="submenu" hidden>
<li><a href="/products/cat1">產品分類一</a></li>
<li><a href="/products/cat2">產品分類二</a></li>
</ul>
</li>
在這段程式碼中:
button 元素用來觸發展開/收合子選單,並加上了 aria-haspopup="true",明確指出它會打開一個選單。
aria-expanded="false" 表示子選單初始為收合狀態。當我們用 JavaScript 監聽按鈕點擊時,應該切換這個值為 "true" 並將子選單 <ul> 顯示出來;再次點擊則相反。
aria-controls="prod-menu" 則將按鈕和下方 id="prod-menu" 的 <ul> 關聯起來,方便輔助技術快速定位子選單容器。
子選單本身我們用了 hidden 屬性(HTML5 全域屬性)來預設隱藏它。這和使用 CSS display:none 有相同視覺效果,同時也隱藏於無障礙樹中。
透過上述 ARIA 標記,當焦點移到「產品分類 ▼」按鈕時,螢幕閱讀器會告知這是一個可開啟子選單的按鈕(因為有 aria-haspopup),且目前處於收合狀態(因為 aria-expanded="false")。使用者按下 Enter 或空白鍵啟動時,我們的腳本會顯示子選單、更新按鈕的 aria-expanded 為 "true",螢幕閱讀器則會隨即通知使用者選單已展開。這確保了即便是看不見畫面的使用者,也能順利地操作下拉選單並瞭解狀態變化。
「無障礙優先」的設計心態
實踐 ARIA 時,記住一條金科玉律:No ARIA is better than bad ARIA(錯誤使用 ARIA 還不如不用)。換言之,如果你不確定某個 ARIA 屬性的用途或正確用法,寧可暫時先不加,因為錯誤的 ARIA 可能讓輔助工具解讀混亂,反而壞了體驗。良好的做法是優先使用原生HTML語意(如 <nav>、適當的標題層級、清單結構),僅在需要時再補充 ARIA 屬性。
在此基礎上,善用我們上面介紹的 aria-current、aria-label、aria-haspopup 等屬性為導覽選單提供輔助資訊。經過無障礙強化的選單,將能讓所有使用者(無論是否仰賴輔助技術)都輕鬆導航網站。
使用 CSS 製作橫向、下拉式與側邊選單樣式
有了穩固的 HTML 結構和無障礙考量,最後我們來談談視覺呈現。透過 CSS,我們可以將相同的清單結構打造成不同風格的選單版面,包括橫向的導覽列、下拉式選單 (dropdown menu),以及垂直的側邊目錄。本節將提供各種樣式的實作要點與範例程式碼。
橫向導覽選單的樣式
默認情況下,<ul> 清單顯示為垂直列表並帶有項目符號。然而在網站的頁首導覽列中,我們通常希望清單項目橫向排布,而且不要清單符號。要達成這點,我們可以使用以下幾步:
移除預設清單樣式:瀏覽器會在 <ul> 上有預設的 padding 和 margin,並為 <li> 加上圓點符號。可透過 CSS 重置這些。例如:
ul { list-style-type: none; margin: 0; padding: 0; }
如此一來,清單符號將被移除,邊距歸零。這通常是橫向或自訂樣式清單的第一步,建立一個「乾淨」的起點。
橫向排列清單項:有幾種方式可以讓 <li> 橫向並排:
將 <li> 設為行內區塊:
li { display: inline-block; }
這會讓多個 <li> 像文字般並排。同時可對 <li> 間距進行調整,例如加些 margin 來隔開。
使用浮動:傳統方法是令 li { float: left; },讓每個項目向左浮動。但要注意清除浮動對父元素的影響。
Flexbox:把父 <ul> 設為 display: flex;,可輕鬆讓子項橫向排列,並具備更強的對齊控制。
這裡我們以 inline-block 為例,它相容性佳且簡單明瞭。藉此,所有選單項目將依序水平排列。
樣式化連結外觀:例如設定背景、文字顏色、hover效果等,使其看起來像按鈕或標籤:
nav ul li a {
display: block; /* 讓<a>填滿<li>範圍,整塊可點擊 */
padding: 10px 15px;
color: #fff;
text-decoration: none;
background-color: #333;
}
nav ul li a:hover {
background-color: #444; /* 滑鼠經過變色 */
}
將 <a> 設為區塊級元素可以更容易地控制尺寸,同時擴大點擊區域,增進使用體驗。
範例:橫向導覽列的 HTML 與 CSS
<nav class="navbar">
<ul>
<li><a href="/">首頁</a></li>
<li><a href="/services">服務項目</a></li>
<li><a href="/pricing">價目表</a></li>
<li><a href="/contact">聯絡我們</a></li>
</ul>
</nav>
/* 移除清單預設樣式,讓背景可視 */
.navbar ul {
list-style: none;
margin: 0; padding: 0;
background-color: #333;
}
/* 橫向排列<li>,以及連結樣式 */
.navbar li { display: inline-block; }
.navbar a {
display: block;
color: #fff;
text-decoration: none;
padding: 12px 20px;
}
.navbar a:hover {
background-color: #444;
}
上述 CSS 使得清單項目橫向排列,整個 .navbar 呈現為一條深色橫幅,每個 <a> 像按鈕一樣並排。將滑鼠懸停在項目上會變色以提供回饋。這樣一來,透過不到十行 CSS,就完成了基本的橫向選單樣式。
下拉式清單(Dropdown Menu)的樣式
當選單項目存在子選單時,就形成了下拉式選單。延續上一節的範例,假設「服務項目」底下有細分類,我們可以在該 <li> 中嵌套一個子 <ul>。HTML 結構例如:
<li class="dropdown">
<a href="/services">服務項目</a>
<ul class="dropdown-menu">
<li><a href="/services/design">- 網頁設計</a></li>
<li><a href="/services/seo">- SEO 優化</a></li>
</ul>
</li>
子清單已在結構上準備就緒,接下來重點是透過 CSS 控制它的顯示與隱藏。一般的CSS實現步驟如下:
隱藏子選單預設顯示:將子選單容器(上例中 .dropdown-menu 對應的 <ul>)設為隱藏:
.dropdown-menu {
display: none;
position: absolute;
background-color: #333;
min-width: 150px;
/* 其他樣式如陰影或邊框可自行添加 */
}
display: none 讓它不佔據版面也不顯示;position: absolute 則脫離正常文檔流,允許我們將它定位在父項下方。通常會將子選單的 top 設為父 <li> 的高度(或使用 top: 100%),left: 0 對齊左側,這樣子選單會剛好垂直地出現在父選單項下方。
滑鼠經過父項時顯示子選單:利用 CSS 選擇器實現 hover 顯示:
.dropdown:hover .dropdown-menu {
display: block;
}
當使用者將滑鼠移到父 <li class="dropdown"> 上時,選中其內部的 .dropdown-menu,將其 display 改為 block 顯示出來。這樣就實現了基本的下拉出現行為。
樣式調整:子選單中的項目多為縱向列出,通常寬度與父項相當或者自行設定最小寬度。可以針對 .dropdown-menu li a 設定樣式,例如和主選單相似的配色、padding,但可能字體略小等。也可在 .dropdown-menu li a:hover 上改變背景突顯。
範例:下拉子選單的 CSS
/* 父選單項設為相對定位,以錨定絕對定位的子選單 */
.dropdown { position: relative; }
/* 子選單容器預設隱藏 */
.dropdown-menu {
display: none;
position: absolute;
top: 100%; left: 0;
background-color: #333;
min-width: 150px;
list-style: none;
margin: 0; padding: 0;
}
/* 當父項目:hover時,顯示子選單 */
.dropdown:hover .dropdown-menu {
display: block;
}
/* 子選單項目的樣式 */
.dropdown-menu li a {
display: block;
padding: 10px;
color: #fff;
text-decoration: none;
white-space: nowrap; /* 單行顯示(避免自動換行) */
}
.dropdown-menu li a:hover {
background-color: #444;
}
以上 CSS 做了幾點處理:
父 .dropdown 元素使用 position: relative,使其子元素的絕對定位基準鎖定在父項上,而不是整個頁面。
子選單 .dropdown-menu 初始為隱藏且絕對定位在父項正下方(top: 100% 意味著緊貼父項底部)。
利用父項的 :hover 狀態切換子選單為顯示。當滑鼠移出父項或子選單時,:hover 失效又會隱藏,達成簡單的懸停開合效果。
子選單的樣式與主選單類似,但我們設置 white-space: nowrap; 防止過長文字折行,可以在項目前加符號區別層級(例如這裡示範用了破折號「-」在 HTML 裡)。
這個CSS下拉菜單方案在桌面環境相當好用。不過需要注意的是:Hover 方式在觸控裝置上不可用。手機和平板上沒有滑鼠懸停,使用者點擊父項時通常會直接導航而不是展開子選單。因此,如前章所述,對於行動裝置我們常會用 JavaScript 來切換子選單(或者使用 <button> 元素而非純連結)。在實作下拉選單時,務必確保行動版有替代方案,例如點擊展開的機制,並結合前述 ARIA 属性(如 aria-expanded)同步更新狀態。這樣可避免手機用戶無法展開選單的窘境,也讓輔助技術用戶獲知子選單的開合。
側邊垂直目錄的樣式
側邊選單(Sidebar menu)或目錄通常是垂直排列的列表,類似 <ul> 的預設呈現,但我們可以透過 CSS 讓它更美觀且易讀。常見的側邊欄目錄樣式包含固定寬度區塊、項目垂直堆疊、目前所在頁的強調標示等。
實作側邊目錄的CSS要點:
父容器可以是 <aside> 或 <nav>,根據佈局需要設置寬度、高度和滾動。如固定在頁面左側,則可能需要 position: fixed; left: 0; top: 0; height: 100%; 等讓其貼齊窗框。
清單項目的樣式方面,移除預設樣式依然適用(無項目符號、無額外邊距)。
每個 <li> 或其中的 <a> 一般設定為 display: block 且佔滿容器寬度。可加入邊框或底線區隔各項目。
為了提升辨識度,通常會在滑過或選取時改變背景色;也可以利用 aria-current 的資訊在 CSS 加強目前頁面的樣式(例如在 [aria-current="page"] 的 <a> 上設定特別的字體或底色)。
範例:側邊欄目錄的CSS
aside nav {
width: 200px;
/* 其他定位或佈局樣式視需求 */
}
aside nav ul {
list-style: none;
margin: 0; padding: 0;
}
aside nav li a {
display: block;
padding: 8px 12px;
color: #333;
text-decoration: none;
border-bottom: 1px solid #ddd;
}
aside nav li a:hover {
background-color: #f0f0f0;
}
aside nav a[aria-current="page"] {
font-weight: bold;
color: #000;
background-color: #e0e0e0;
}
這段CSS將側欄寬度定為200px,清單項目以區塊方式平鋪。每個項目有淡灰色的底線分隔,滑過時背景變更以突出。並且,我們特地對 aria-current="page" 的鏈結設計了不同樣式:粗體文字、深色前景及稍深的背景,強調目前所在位置。由於我們在HTML中會為當前頁連結加上 aria-current="page"(如前述),這裡透過屬性選擇器即可套用特定樣式,非常方便。
側邊欄目錄通常是一直可見的(特別在桌面寬螢幕),因此相較於下拉選單,無需隱藏顯示的切換機制。但在窄螢幕時,若側欄過長導致內容壓縮,仍可能考慮將其改作頂部選單或折疊面板。因此,響應式的思維仍適用於側邊目錄——或許在手機上將其變為漢堡選單形式。
透過以上各種CSS技巧,我們可以將語意單純的HTML清單轉變為風格多樣的導覽介面,而不需改動HTML結構。在維護上,HTML 結構與鏈結順序不變,只調整 CSS 就能切換導覽呈現,既彈性又高效。
常見問與答 Q&A
最後,我們彙整幾個開發者常見的疑問,快速解答有關 HTML 清單與選單設計的問題:
問:<ul> 和 <ol> 在實務上有什麼差異?我應該在什麼情況下用哪一個?
答: <ul>(無序清單)與 <ol>(有序清單)的主要差異在於是否暗示「順序意義」。如果清單項目的排列順序對內容意義沒有影響,用 <ul> 最合適,例如網站導航連結或要點列表。反之,如果順序有意義(例如步驟流程、排名列表),就應選擇 <ol>,因為預設會呈現編號,語意上也表達了先後關係。拿導覽選單來說,大部分情況下沒有嚴格順序,因此會用 <ul>。但在一些特殊導覽形式中會用到 <ol>,例如Breadcrumb麵包屑導航(代表層級位置的先後順序)或多步驟流程導航。在這些情況下,使用 <ol> 更能體現結構順序,同時也利於無障礙:螢幕閱讀器會告知「有序清單,第 X 項…」,使用者能瞭解自己位於第幾步。
問:可以將 <ul> 同時用於主選單和下拉子選單嗎?巢狀清單有限制深度嗎?
答: 可以,而且這是建立階層式選單的推薦做法!HTML 允許清單元素無限深度地巢狀使用。也就是說,你完全可以在 <ul> 的某個 <li> 裡再嵌套一個子 <ul>,以此表示次級選單,繼續嵌套則表示第三級選單,依此類推。瀏覽器對巢狀清單會適當地縮排顯示,而我們通常會用 CSS 來改變這種縮排或改成下拉效果(如前文示範)。需要注意的是:巢狀深度雖然沒有嚴格限制,但過多層級的選單可能在使用上造成困惑,特別是在行動裝置上版面有限。因此建議保持選單結構的層級在可掌握的範圍(通常不超過三層)。技術上 <ul> 和 <ol> 可以交錯巢狀,但在導覽中一般統一用 <ul> 會比較一致。總之,放心地使用巢狀 <ul> 來構建子選單吧,並搭配適當的 CSS/JS 讓它們顯現或隱藏即可。
問:ARIA 屬性是必須的嗎?如果不加會怎樣?
答: ARIA 屬性不是強制性的標準,但在特定情境下強烈建議使用。對於簡單的靜態導覽列,僅靠語意良好的 HTML(例如 <nav>、適當的標題和清單結構)已相當可及,螢幕閱讀器能識別清單及鏈結並朗讀。然而,當我們涉及互動式的選單(如可展開的下拉選單、漢堡選單)時,ARIA 就變得非常重要了。它可以告知輔助技術「某按鈕控制一個子選單」(aria-haspopup)、「子選單目前展開還是收合」(aria-expanded)、「哪個連結是目前頁」(aria-current)等等。這些資訊對視障使用者等而言就是操作指引,沒有 ARIA 他們可能不知道子選單存在或無法確定當前所在頁面。
反之,不當的 ARIA 使用可能造成誤導,所以如果不確定就暫時不要亂加。總的原則是:語意優先,ARIA 補充。在語意良好的前提下,適度加入 ARIA 能大幅改善無障礙體驗。如果完全不使用 ARIA,你的選單在視覺上對一般用戶可能沒問題,但對使用輔助技術的用戶就少了一層提示與保護。所以我們鼓勵在理解ARIA用途的基礎上運用它,使網站更加友善。舉例而言,如果你的選單沒有任何下拉或特別互動,那不加 ARIA 也許影響不大;但只要有動態展開的部分,就應該用 ARIA 來及時反映狀態。
問:有必要把 <nav> 裡的連結都包在 <ul> 嗎?直接放多個 <a> 不行嗎?
答: 前面其實有討論到,直接多個 <a> 在語法上是允許的,但不包在清單中會失去一些結構上的語意益處。使用清單能明確告訴瀏覽器和開發者,這是一組相關的項目。特別是輔助技術會將其視為「清單」,提供如項目數量的資訊。此外,在樣式控制上,用 <ul><li> 容易很多——可以一次調整整個群組的 margin/padding、垂直排列或水平排列;而裸露的一堆 <a> 在沒有父級 <ul> 時,你可能需要用其他辦法(如包裝在 <div> 再逐個處理間距)。清單還可自然地承載子清單,用於階層式選單。綜合來說,將連結清單化是更好的習慣。除非你的導覽結構極其簡單(例如只有一兩個連結),大多數情況下還是建議使用 <ul> 包裹導覽項目,以保持 HTML 結構清晰。
結語
透過本篇教學,我們可以看到僅靠 HTML 提供的清單元素,就能構築出功能強大且靈活的導覽選單和目錄結構。我們從基本的 <ul>, <ol>, <dl> 說起,了解它們在導覽和內容目錄中的語意作用,再到響應式設計讓清單選單適應各種螢幕,以及應用 ARIA 提升無障礙表現。最後,我們運用 CSS 打造出不同樣式的選單版型,包括橫幅導航列、下拉式子選單和垂直側邊目錄,並解答了一些實務上的常見疑問。
前端開發既是工程也是藝術——透過語意正確的 HTML 打底,配合聰明的 CSS 和必要的 JS,我們可以將簡單的清單轉變為網站的導航中樞。在追求美觀和互動的同時,也別忘了內在的語意與可及性,讓我們的導覽對每一位使用者都友好。希望這篇文章提供的範例和原則能對你有所啟發。現在,請拿起這些知識,試著在你的專案中實踐吧!清單式導覽設計的妙用,等你親自去發掘與創造。