HTML 輸入控制元素讓使用者輸入資料、選擇選項,以及執行操作。
它們常見於搜尋、課程報名、檔案上載及發送查詢等表單。
常用控制元素包括:
| 元素 | 用途 |
|---|---|
<input> | 文字、選項、日期、檔案及其他輸入類型 |
<textarea> | 多行文字 |
<select> | 從清單中選擇 |
<button> | 提交或執行其他操作 |
<label> | 識別控制元素 |
<fieldset> | 組合相關控制元素 |
<legend> | 為欄位群組提供名稱 |
按所需資料選擇控制元素,提供清晰標籤,並在可行的情況下使用原生 HTML 行為。
17.1 表單內的控制元素
<form> 將控制元素組合起來,用於收集及提交資料:
<form action="/course-enquiries" method="post">
<label for="full-name">姓名</label>
<input
id="full-name"
name="fullName"
type="text"
autocomplete="name"
required
>
<button type="submit">發送查詢</button>
</form>在這個例子中:
action指定提交目的地。method指定表單的提交方法。name識別控制元素提交的值。required表示必須完成該欄位,才能通過原生驗證。
目的地必須具備適當的伺服器端處理功能。單靠 HTML 不會儲存查詢或發送電郵。
不要將一個 <form> 嵌套在另一個 <form> 內。
17.2 <input> 元素
<input> 是空元素,沒有結束標籤。
它的 type 決定輸入行為:
<input type="text" name="courseSearch">省略 type 時,預設為 text。
常見類型包括:
| 類型 | 常見用途 |
|---|---|
text | 單行文字 |
search | 搜尋字句 |
email | 電郵地址 |
password | 遮蔽顯示的文字輸入 |
tel | 電話號碼 |
url | 網址 |
number | 數值或數量 |
date | 日期 |
time | 時間 |
checkbox | 獨立選項 |
radio | 同一組內的單選選項 |
file | 選取檔案 |
range | 在刻度範圍內選擇數值 |
color | 選擇顏色 |
hidden | 不顯示的表單資料 |
不同瀏覽器及裝置的外觀和操作方式可能不同。
17.3 標籤、識別碼與名稱
可見的 <label> 告訴讀者控制元素的用途:
<label for="email-address">電郵地址</label>
<input
id="email-address"
name="email"
type="email"
autocomplete="email"
>標籤的 for 值必須與輸入元素的 id 相同。
各屬性有不同職責:
id:識別元素,並將它與標籤連接。name:識別提交時的資料值。type:選擇輸入行為。
沒有 name 的控制元素,通常不會在表單提交中提供具名資料值。
點擊或輕觸已連接的標籤,也有助啟動控制元素或讓它取得焦點。
標籤也可以包住輸入元素:
<label>
電郵地址
<input name="email" type="email">
</label>明確使用 for 與 id,通常更方便配合不同版面。
17.4 填寫說明與預留位置文字
填寫欄位時需要的資訊,應以可見說明提供:
<label for="display-name">顯示名稱</label>
<input
id="display-name"
name="displayName"
type="text"
maxlength="40"
aria-describedby="display-name-help"
>
<p id="display-name-help">
最多可輸入 40 個字元。
</p>aria-describedby 將控制元素與補充文字連接起來。
placeholder 可以提供範例:
<label for="course-search">搜尋課程</label>
<input
id="course-search"
name="query"
type="search"
placeholder="例如:HTML"
>預留位置文字不能取代標籤。 它會在輸入時消失,而且可能不容易閱讀。
17.5 文字、電郵、電話與密碼欄位
以下片段示範各類欄位的設定;實際使用時,每個欄位仍應有適當標籤。
一般文字
<input
id="full-name"
name="fullName"
type="text"
autocomplete="name"
>避免對姓名設定不必要的嚴格格式。姓名可能包含空格、標點,以及不同書寫系統的字元。
電郵地址
<input
id="email"
name="email"
type="email"
autocomplete="email"
required
>type="email" 提供基本格式驗證,但不會證明地址存在,也不會確認地址屬於訪客。
電話號碼
<input
id="telephone"
name="telephone"
type="tel"
autocomplete="tel"
>不同國家及地區的電話格式不同,因此 tel 不會強制使用統一格式。
密碼
<input
id="account-password"
name="password"
type="password"
autocomplete="new-password"
required
>密碼遮蔽只會改變顯示方式,不會加密提交的資料。
應使用 HTTPS 及適當的伺服器端安全措施。輸入現有帳戶的登入密碼時,使用 autocomplete="current-password"。
17.6 數值、日期與輸入提示
數量資料可以使用 number:
<label for="places">報名名額數量</label>
<input
id="places"
name="places"
type="number"
min="1"
max="6"
step="1"
value="1"
>不要只因資料包含數字,就使用數值欄位。電話號碼、郵政編碼及帳戶識別碼不是數量。
由數字組成的識別碼,可能更適合文字欄位配合鍵盤提示:
<input
id="reference-code"
name="referenceCode"
type="text"
inputmode="numeric"
>inputmode 提示適合的輸入方式,例如數字鍵盤;它不會驗證資料值。
日期欄位:
<label for="preferred-date">首選日期</label>
<input
id="preferred-date"
name="preferredDate"
type="date"
>介面可能使用本地日期格式,但控制元素的值使用標準的年、月、日格式:YYYY-MM-DD。
17.7 使用 <textarea> 輸入多行文字
訊息及較長回覆可以使用 <textarea>:
<label for="message">你的訊息</label>
<textarea
id="message"
name="message"
rows="5"
maxlength="2000"
></textarea>與 <input> 不同,<textarea> 需要結束標籤。
初始值放在標籤之間:
<textarea name="message" rows="5">我想查詢……</textarea>不要使用 value 屬性設定初始文字。
應提供足夠的書寫空間,並避免在沒有充分理由下阻止使用者調整控制元素大小。
17.8 從清單中選擇
使用 <select> 和 <option> 提供選項清單:
<label for="course">課程</label>
<select id="course" name="course" required>
<option value="">請選擇課程</option>
<option value="html-basics">HTML 入門</option>
<option value="css-basics">CSS 入門</option>
<option value="javascript-basics">JavaScript 入門</option>
</select>提交時會使用已選選項的 value。
對必填的單選清單,初始空值選項可以提示使用者作出明確選擇。
使用 selected 提供預設選項:
<option value="html-basics" selected>HTML 入門</option>相關選項可以分組:
<select name="course">
<optgroup label="入門程度">
<option value="html-basics">HTML 入門</option>
<option value="css-basics">CSS 入門</option>
</optgroup>
</select>multiple 允許選擇多項,但操作方式不一定清晰。對較短的清單,核取方塊可能更容易使用。
17.9 核取方塊
核取方塊表示獨立選項:
<label>
<input
type="checkbox"
name="updates"
value="yes"
>
向我發送課程最新資訊
</label>未勾選的核取方塊,通常不會在提交時提供資料值。
已勾選的核取方塊會提交其 value。如果省略該屬性,預設提交值為 "on"。
使用 checked 設定初始勾選狀態:
<input type="checkbox" name="updates" value="yes" checked>checked 是布林屬性。寫成 checked="false",仍然代表屬性存在,因此初始狀態仍是已勾選。
不要只為方便,就預先勾選非必要的同意選項。
17.10 單選按鈕與群組標籤
單選按鈕讓使用者在同一組中選擇一項。
相關單選按鈕應使用相同 name,以及不同的值:
<fieldset>
<legend>首選上課時段</legend>
<label>
<input
type="radio"
name="session"
value="morning"
required
>
上午
</label>
<label>
<input
type="radio"
name="session"
value="afternoon"
required
>
下午
</label>
</fieldset><fieldset> 組合控制元素,<legend> 則為群組提供名稱。
只有已選取的單選按鈕值會提交。
每個單選按鈕仍然需要自己的標籤。群組的 <legend> 不能取代個別標籤。
17.11 檔案輸入欄位
使用 type="file" 讓訪客選擇檔案:
<label for="attachment">附加文件</label>
<input
id="attachment"
name="attachment"
type="file"
accept=".pdf"
>accept 引導檔案選擇,但不能可靠地強制檔案類型,也不會令上載變得安全。
使用原生表單提交檔案時,表單需要以下設定:
<form
action="/upload"
method="post"
enctype="multipart/form-data"
>
<!-- 檔案控制元素及提交按鈕。 -->
</form>伺服器必須驗證檔案大小、實際內容、權限及儲存處理方式。
檔案輸入欄位不能偷偷選取訪客電腦上的任意檔案。
17.12 按鈕及其類型
明確指定按鈕類型:
<button type="submit">發送查詢</button>
<button type="button">顯示說明</button>
<button type="reset">重設表單</button>| 類型 | 行為 |
|---|---|
submit | 提交所屬表單 |
button | 沒有預設提交操作 |
reset | 將控制元素還原至初始值 |
一般與表單關聯的 <button>,如果省略類型,會預設用作提交。
重設按鈕可能意外清除使用者的輸入,因此除非有明確需要,否則應避免提供。
17.13 驗證與控制狀態
HTML 提供基本限制驗證:
| 屬性 | 用途 |
|---|---|
required | 必須提供值或作出適用的選擇 |
minlength / maxlength | 文字長度限制 |
min / max | 支援類型的數值或日期限制 |
step | 允許的步距 |
pattern | 支援的文字輸入類型所使用的正規表示式限制 |
應以可見文字說明限制,不要讓訪客只在發生錯誤後才發現要求。
停用與唯讀
<input name="courseCode" value="HTML-101" readonly>
<input name="unavailableOption" value="暫不提供" disabled>readonly:阻止編輯適用的控制元素,但值仍然可以提交。disabled:阻止一般操作,而且控制元素不會包含在提交資料中。
兩者都不能防止資料值被修改或偽造。
瀏覽器驗證可以改善操作體驗,但所有提交資料仍必須在伺服器端驗證。
17.14 完整範例:課程查詢控制元素
以下示範包含已標示的文字欄位、選項清單、單選按鈕、核取方塊及多行文字欄位。
它會在本頁驗證表單並顯示狀態訊息,不會發送或儲存查詢。
id: hong-kong-html-input-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;
}
.field > label,
legend {
font-weight: 700;
}
.field > label {
display: block;
margin-block-end: 0.4rem;
}
input:not([type="radio"]):not([type="checkbox"]),
select,
textarea {
display: block;
width: 100%;
padding: 0.65rem;
border: 1px solid #767676;
border-radius: 0.25rem;
color: #222;
background: white;
font: inherit;
}
textarea {
resize: vertical;
min-height: 8rem;
}
fieldset {
min-width: 0;
margin: 0 0 1.5rem;
padding: 1rem;
border: 1px solid #767676;
border-radius: 0.25rem;
}
.choice {
display: flex;
align-items: flex-start;
gap: 0.6rem;
padding-block: 0.5rem;
}
.choice input {
flex-shrink: 0;
margin-block-start: 0.55rem;
}
.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;
}
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
button:focus-visible {
outline: 3px solid #005ea8;
outline-offset: 3px;
}
#demo-status {
margin-block: 1rem 0;
}
</style>
</head>
<body>
<main>
<h1>課程查詢示範</h1>
<p class="note">
練習使用表單控制元素。
本頁不會發送或儲存你輸入的資料。
請使用範例資料,不要填寫個人資料。
</p>
<form id="enquiry-form">
<p>標示「必填」或「必選」的項目必須完成。</p>
<div class="field">
<label for="full-name">姓名(必填)</label>
<input
id="full-name"
name="fullName"
type="text"
autocomplete="name"
required
>
</div>
<div class="field">
<label for="email">電郵地址(必填)</label>
<input
id="email"
name="email"
type="email"
autocomplete="email"
aria-describedby="email-help"
required
>
<p id="email-help" class="help">
此示範可以使用 [email protected]。
</p>
</div>
<div class="field">
<label for="course">課程(必選)</label>
<select id="course" name="course" required>
<option value="">請選擇課程</option>
<option value="html-basics">HTML 入門</option>
<option value="css-basics">CSS 入門</option>
<option value="javascript-basics">JavaScript 入門</option>
</select>
</div>
<fieldset>
<legend>首選上課時段(必選)</legend>
<label class="choice">
<input
type="radio"
name="session"
value="morning"
required
>
<span>上午</span>
</label>
<label class="choice">
<input
type="radio"
name="session"
value="afternoon"
required
>
<span>下午</span>
</label>
</fieldset>
<div class="field">
<label for="message">訊息(選填)</label>
<textarea
id="message"
name="message"
rows="5"
maxlength="1000"
aria-describedby="message-help"
></textarea>
<p id="message-help" class="help">
最多 1,000 個字元。請勿包含機密資料。
</p>
</div>
<div class="field">
<label class="choice">
<input type="checkbox" name="updates" value="yes">
<span>
在這份範例查詢中選擇接收課程最新資訊(選填)
</span>
</label>
</div>
<button id="check-button" type="submit" disabled>
檢查範例查詢
</button>
<p id="demo-status" role="status" aria-atomic="true">
互動檢查功能需要 JavaScript。
</p>
</form>
</main>
<script>
const form = document.getElementById("enquiry-form");
const button = document.getElementById("check-button");
const status = document.getElementById("demo-status");
// 阻止提交,包括按 Enter 觸發的隱式提交。
form.addEventListener("submit", (event) => {
event.preventDefault();
const data = new FormData(form);
const updates = data.has("updates")
? "已選擇接收課程最新資訊。"
: "未選擇接收課程最新資訊。";
status.textContent =
`範例查詢已通過瀏覽器驗證。${updates}` +
"沒有發送或儲存任何資料。";
});
status.textContent =
"已準備好檢查範例查詢,不會發送任何資料。";
button.disabled = false;
</script>
</body>
</html>在這個範例中:
- 標籤識別每個輸入控制元素。
name屬性識別表單資料值。<fieldset>和<legend>將時段選項組合起來。- 原生驗證會在提交事件之前檢查必填欄位。
FormData讀取目前的表單值。- JavaScript 阻止提交導覽,並顯示狀態訊息。
- JavaScript 無法使用時,檢查按鈕會保持停用。
實際查詢服務需要適當的提交端點、伺服器端驗證、私隱說明,以及安全的資料處理。
17.15 常見錯誤
| 錯誤 | 較好的做法 |
|---|---|
| 使用預留位置文字代替標籤 | 提供持續可見的標籤 |
控制元素有 id,但沒有 name | 需要提交值時加入 name |
| 使用數值欄位輸入電話號碼 | 使用 tel |
| 相關單選按鈕使用不同名稱 | 使用相同的群組名稱 |
以為未勾選的核取方塊會提交 "false" | 明確處理該欄位沒有提交值的情況 |
使用 checked="false" 或 disabled="false" | 移除布林屬性以取消狀態 |
使用 value 設定多行文字的初始值 | 將文字放在標籤之間 |
| 省略按鈕類型 | 指定 submit、button 或 reset |
| 將檔案選取提示視為安全檢查 | 在伺服器端驗證上載檔案 |
| 以為密碼遮蔽會加密資料 | 使用 HTTPS 及安全處理 |
| 只相信瀏覽器驗證 | 在伺服器端驗證所有提交資料 |
| 不必要地建立自訂控制元素 | 優先使用具備無障礙功能的原生元素 |
本章總結: 輸入控制元素收集文字、選項、檔案及其他資料值。使用適當類型、清晰標籤、有意義的群組,以及明確的按鈕行為。原生驗證有助使用者完成表單,但安全提交及權威驗證仍需要伺服器端處理。















