HTML 提供原生控制元素,讓使用者從選項清單中作出選擇。
主要元素包括:
| 元素 | 用途 |
|---|---|
<select> | 提供選擇控制元素 |
<option> | 定義可用選項 |
<optgroup> | 將相關選項分組 |
<datalist> | 為輸入欄位提供建議,而不是限制只能使用列出的選項 |
<label for="course">選擇課程</label>
<select id="course" name="course">
<option value="html">HTML 基礎</option>
<option value="css">CSS 基礎</option>
<option value="javascript">JavaScript 基礎</option>
</select>只要原生選擇控制元素能滿足介面需要,就應優先使用它們。 它們提供內建鍵盤操作、表單整合及無障礙支援。
27.1 <select> 元素
<select> 包含使用者可以選擇的選項:
<label for="session">首選上課時段</label>
<select id="session" name="session">
<option value="morning">上午</option>
<option value="afternoon">下午</option>
<option value="evening">晚上</option>
</select>單選控制元素通常顯示為下拉選單。實際外觀及操作方式取決於瀏覽器和作業系統。
重要屬性包括:
| 屬性 | 用途 |
|---|---|
id | 將控制元素與標籤連接 |
name | 識別提交的值 |
required | 要求有效選擇 |
disabled | 令控制元素不可操作 |
multiple | 允許選取多個選項 |
size | 要求顯示指定數目的選項列 |
form | 透過 ID 將控制元素與表單關聯 |
<select> 需要結束標籤。
27.2 <option> 元素
每個 <option> 定義一個選項:
<option value="html">HTML 基礎</option>可見文字與提交值具有不同用途:
- 可見文字:幫助使用者識別選項。
value:提供表單提交及程式碼使用的值。
如果省略 value,選項值會從其文字內容取得。
通常應明確設定值:
<option value="intro-html">HTML 入門介紹</option>這樣可以改變可見文字,而不會意外改變應用程式使用的識別碼。
為了讓入門標記更清晰,應明確寫出選項的結束標籤。
27.3 初始選擇
使用 selected 設定初始選取的選項:
<label for="language">首選語言</label>
<select id="language" name="language">
<option value="en" selected>英文</option>
<option value="zh-Hant">繁體中文</option>
</select>一般單選下拉選單如果沒有指定選擇,瀏覽器通常會選取第一個可用選項。
不要假設使用者會注意到系統已作出預設選擇。應謹慎設定預設值,尤其當選擇涉及費用、私隱或法律後果時。
selected 是布林屬性:
<!-- 這仍然表示選項初始已被選取。 -->
<option value="en" selected="false">英文</option>如果不想指定初始選擇,應移除該屬性。
27.4 要求明確選擇
必選的單選下拉選單,可以以空值提示選項開始:
<label for="course">課程(必選)</label>
<select id="course" name="course" required>
<option value="" selected>請選擇課程</option>
<option value="html">HTML 基礎</option>
<option value="css">CSS 基礎</option>
</select>這種模式中的初始空值選項,不符合必選要求。
標準提示選項行為需要:
- 單選的
<select>。 - 顯示大小為一列。
- 第一個選項具有空值,而且是
<select>的直接子元素。
提示文字不能取代標籤。
你可以停用提示選項,但應考慮使用者是否需要返回未選擇狀態。對非必選欄位,可選取的「沒有偏好」選項通常很有用。
27.5 使用 <optgroup> 分組
使用 <optgroup> 組織相關選項:
<label for="course">選擇課程</label>
<select id="course" name="course">
<optgroup label="入門程度">
<option value="html">HTML 基礎</option>
<option value="css">CSS 基礎</option>
</optgroup>
<optgroup label="中級程度">
<option value="javascript">JavaScript 應用</option>
<option value="accessibility">網頁無障礙功能</option>
</optgroup>
</select>群組的 label 提供顯示名稱。
重要事項包括:
- 群組標題不是可選取的選項。
<optgroup>不能互相嵌套。- 群組名稱應幫助使用者理解組織方式。
- 短清單應避免過度分組。
27.6 停用控制元素與選項
個別選項不可用時,可以將它停用:
<option value="evening" disabled>
晚上 — 名額已滿
</option>停用整個群組:
<optgroup label="進階課程 — 暫不提供" disabled>
<option value="advanced-js">進階 JavaScript</option>
<option value="performance">網頁效能</option>
</optgroup>停用整個控制元素:
<label for="session">上課時段選擇</label>
<select id="session" name="session" disabled>
<option value="">暫時未提供上課時段</option>
</select>停用的 <select>:
- 通常不能操作,也不能透過一般 Tab 次序到達。
- 不參與原生限制驗證。
- 不包含在一般表單提交中。
如果不可用的原因不明顯,應提供可見說明。
<select> 不支援 readonly。另外,單靠 aria-disabled="true" 不會停用原生操作或提交。
27.7 多項選擇
加入 multiple,允許選取多個選項:
<label for="topics">感興趣的主題</label>
<select
id="topics"
name="topics"
multiple
size="4"
aria-describedby="topics-help"
>
<option value="html">HTML</option>
<option value="css">CSS</option>
<option value="javascript">JavaScript</option>
<option value="accessibility">無障礙功能</option>
</select>
<p id="topics-help">
你可以選擇多個主題。
選取操作方式取決於你的裝置。
</p>多選控制元素通常顯示為清單,而不是緊湊的下拉選單。
桌面操作可能需要配合修飾鍵,但不同平台的行為不同。不要假設同一套鍵盤指引適用於所有裝置。
對少量獨立選項,具有標籤的核取方塊通常更容易理解及使用。
27.8 size 屬性
size 要求控制元素顯示指定數目的選項列:
<label for="session">選擇一個上課時段</label>
<select id="session" name="session" size="3">
<option value="morning">上午</option>
<option value="afternoon">下午</option>
<option value="evening">晚上</option>
</select>這個控制元素仍然只允許選取一個選項,因為沒有 multiple。
顯示多列不代表啟用多項選擇。
實際呈現方式取決於瀏覽器及裝置。
27.9 使用 JavaScript 讀取選擇
單選控制元素可以透過 .value 讀取:
const course = document.getElementById("course");
console.log(course.value);多選控制元素可以透過 selectedOptions 讀取:
const topics = document.getElementById("topics");
const selectedValues = Array.from(
topics.selectedOptions,
(option) => option.value
);多選控制元素的 .value 只會返回第一個已選選項的值,而不是包含所有選擇的陣列。
回應已確認的選擇變更:
course.addEventListener("change", () => {
console.log(course.value);
});避免只因使用者改變選擇,就自動提交表單或前往另一個網頁。獨立操作按鈕通常更容易預期。
27.10 表單提交
表單內具有名稱的 <select>,會提交已選選項的值:
<form action="/course-enquiry" method="post">
<label for="course">課程</label>
<select id="course" name="course">
<option value="html">HTML 基礎</option>
<option value="css">CSS 基礎</option>
</select>
<button type="submit">發送查詢</button>
</form>選擇 HTML 會產生名稱為 course、值為 html 的欄位。
多選控制元素中,已選且未停用的選項會以相同名稱產生多個資料項目。
可以使用 FormData 查看:
const data = new FormData(form);
const topics = data.getAll("topics");topics[] 這類名稱是部分伺服器框架使用的慣例,不是 HTML 要求。
應在伺服器端驗證提交值。使用者可以修改用戶端標記,或不經表單直接發送請求。
27.11 <datalist>:建議,而不是限制
<datalist> 為輸入欄位提供建議:
<label for="course-search">感興趣的課程</label>
<input
id="course-search"
name="courseInterest"
type="text"
list="course-suggestions"
>
<datalist id="course-suggestions">
<option value="HTML 基礎"></option>
<option value="CSS 基礎"></option>
<option value="網頁無障礙功能"></option>
</datalist>輸入欄位的 list 參照 <datalist> 的 ID。
與 <select> 不同,配合 <datalist> 的文字輸入欄位允許輸入未列出的值。
| 特點 | <select> | 配合 <datalist> 的文字輸入欄位 |
|---|---|---|
| 是否限制只能選擇列出的選項 | 一般操作下是 | 否 |
| 是否允許輸入任意文字 | 否 | 是 |
| 提交值來源 | 已選選項 | 輸入欄位值 |
| 原生呈現方式 | 選擇介面 | 附有建議的輸入欄位 |
<datalist> 的呈現方式及無障礙支援各有不同。應使用目標瀏覽器及輔助技術測試。
應將它用作有用建議,而不是唯一的允許值限制方式。
27.12 無障礙功能與樣式
良好的選擇控制元素應具有:
- 持續可見、有意義的標籤。
- 清晰的選項文字。
- 操作方式不明顯時所需的指引。
- 可見焦點提示。
- 選擇之後可預期的操作。
- 按需要與控制元素關聯的錯誤訊息。
基本樣式設定很直接:
select {
display: block;
width: 100%;
padding: 0.65rem;
border: 1px solid #767676;
border-radius: 0.25rem;
color: #222;
background-color: white;
font: inherit;
}
select:focus-visible {
outline: 3px solid #005ea8;
outline-offset: 3px;
}傳統原生選項選單在不同瀏覽器及作業系統中,具有不同的樣式限制及呈現方式。
不要移除下拉指示,除非提供同樣清晰的替代。完全自訂的選擇元件需要仔細實作焦點、鍵盤導覽、選取狀態及無障礙名稱。
27.13 完整範例:課程選擇
以下獨立示範結合:
- 必選課程下拉選單。
- 分組選項。
- 非必選的上課時段偏好。
- 多選主題清單。
- 在本頁顯示已選值的摘要。
網頁不會提交或儲存任何資料。
id: hong-kong-html-selection-menu-controls
name: 選單控制元素 — 課程偏好
type: html
content: |-
<!doctype html>
<html lang="zh-Hant-HK">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>選單控制元素 | 課程偏好</title>
<style>
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
margin: 0;
color: #222;
background: #f5f7fa;
font-family: system-ui, sans-serif;
line-height: 1.8;
}
main {
max-width: 42rem;
margin-inline: auto;
padding: 2rem 1rem;
}
h1 {
color: #005ea8;
line-height: 1.4;
}
form {
padding: 1.25rem;
border: 1px solid #767676;
border-radius: 0.5rem;
background: white;
}
.field {
margin-block-end: 1.5rem;
}
label {
display: block;
margin-block-end: 0.4rem;
font-weight: 700;
}
select {
display: block;
width: 100%;
padding: 0.65rem;
border: 1px solid #767676;
border-radius: 0.25rem;
color: #222;
background-color: white;
font: inherit;
}
.help {
margin-block: 0.4rem 0;
color: #4b5563;
}
.note {
padding: 1rem;
border-inline-start: 4px solid #005ea8;
background: #eaf2f8;
}
button {
padding: 0.65rem 1rem;
border: 2px solid #005ea8;
border-radius: 0.25rem;
color: white;
background: #005ea8;
font: inherit;
cursor: pointer;
}
button:disabled {
color: #444;
background: #e0e0e0;
border-color: #767676;
cursor: not-allowed;
}
:focus-visible {
outline: 3px solid #005ea8;
outline-offset: 3px;
}
#selection-summary {
margin-block-start: 1.5rem;
padding: 1rem;
border-inline-start: 4px solid #005ea8;
background: #eaf2f8;
}
</style>
</head>
<body>
<main>
<h1>課程偏好</h1>
<p class="note">
選擇範例偏好,然後在本頁顯示摘要。
本頁不會提交或儲存你的選擇。
</p>
<form id="preferences-form">
<div class="field">
<label for="course">課程(必選)</label>
<select id="course" name="course" required>
<option value="" selected>請選擇課程</option>
<optgroup label="入門程度">
<option value="html">HTML 基礎</option>
<option value="css">CSS 基礎</option>
</optgroup>
<optgroup label="中級程度">
<option value="javascript">
JavaScript 應用
</option>
<option value="accessibility">
網頁無障礙功能
</option>
</optgroup>
</select>
</div>
<div class="field">
<label for="session">首選上課時段(選填)</label>
<select
id="session"
name="session"
aria-describedby="session-help"
>
<option value="">沒有偏好</option>
<option value="morning">上午</option>
<option value="afternoon">下午</option>
<option value="evening" disabled>
晚上 — 暫不提供
</option>
</select>
<p id="session-help" class="help">
目前不提供晚上時段。
</p>
</div>
<div class="field">
<label for="topics">感興趣的主題(選填)</label>
<select
id="topics"
name="topics"
multiple
size="4"
aria-describedby="topics-help"
>
<option value="structure">網頁結構</option>
<option value="forms">無障礙表單</option>
<option value="media">音訊及影片</option>
<option value="responsive">響應式版面</option>
</select>
<p id="topics-help" class="help">
你可以選擇多個主題。
選取操作方式取決於你的裝置。
不必選擇任何主題。
</p>
</div>
<button id="summary-button" type="submit" disabled>
顯示選擇摘要
</button>
<p id="selection-summary" role="status" aria-atomic="true">
在本頁顯示摘要需要 JavaScript。
</p>
</form>
</main>
<script>
const form = document.getElementById("preferences-form");
const course = document.getElementById("course");
const session = document.getElementById("session");
const topics = document.getElementById("topics");
const button = document.getElementById("summary-button");
const summary = document.getElementById("selection-summary");
form.addEventListener("submit", (event) => {
event.preventDefault();
const courseText =
course.selectedOptions[0].textContent.trim();
const sessionText =
session.selectedOptions[0].textContent.trim();
const topicTexts = Array.from(
topics.selectedOptions,
(option) => option.textContent.trim()
);
const topicSummary = topicTexts.length
? topicTexts.join("、")
: "未選擇";
summary.textContent =
`課程:${courseText}。` +
`時段:${sessionText}。` +
`主題:${topicSummary}。` +
"沒有提交或儲存任何資料。";
});
button.disabled = false;
summary.textContent =
"請選擇偏好,然後顯示摘要。";
</script>
</body>
</html>在這個範例中:
- 每個
<select>都具有持續可見的標籤。 - 必選課程以空值提示選項開始。
- 選項群組組織不同課程。
- 非必選時段包含「沒有偏好」。
- 不可用時段具有可見說明。
- 主題清單允許多項選擇。
submit處理程式執行之前,原生驗證會檢查必選課程。- JavaScript 透過
selectedOptions讀取所有已選主題。 - 使用者啟動按鈕後,摘要才會更新。
對這類短主題清單,核取方塊也是合理選擇,而且通常更容易理解操作方式。
27.14 常見錯誤
| 錯誤 | 較好的做法 |
|---|---|
| 只使用提示選項作為標籤 | 提供持續可見的標籤 |
需要提交值時省略 name | 為選單提供適當欄位名稱 |
以為 size 會啟用多項選擇 | 明確加入 multiple |
只從多選控制元素讀取 .value | 使用 selectedOptions 或 FormData.getAll() |
寫成 selected="false" | 移除布林屬性 |
| 以為停用選單會提交資料 | 考慮它不包含在表單資料中的情況 |
為 <select> 使用 readonly | 選擇適當替代方式 |
| 將 datalist 建議當成強制選項 | 驗證值或使用 <select> |
| 選擇後自動前往另一頁 | 提供清晰操作按鈕 |
| 依靠選項顏色傳達意思 | 使用有意義的文字 |
| 建立沒有完整鍵盤支援的自訂下拉選單 | 優先使用原生控制元素 |
| 相信提交的選項值 | 在伺服器端驗證 |
本章總結: 使用 <select> 和 <option> 提供固定清單中的選擇,使用 <optgroup> 組織選項,需要選取多項時加入 multiple。提供清晰標籤及可預期操作。<datalist> 只用來提供建議,而提交的選擇仍須在伺服器端驗證。















