label 關聯:最基本、最常被跳過的

<!-- ❌ placeholder 代替 label:使用者輸入後看不到提示 -->
<input type="text" placeholder="姓名">
 
<!-- ✅ 方法一:for + id 關聯 -->
<label for="name">姓名</label>
<input type="text" id="name" name="name">
 
<!-- ✅ 方法二:label 包起來(不需要 id) -->
<label>
  姓名
  <input type="text" name="name">
</label>

label 的作用不只是視覺文字——點擊 label 文字會聚焦到對應的 input,螢幕閱讀器會朗讀 label 內容。沒有 label 只有 placeholder,使用者輸入後就失去提示,螢幕閱讀器使用者完全不知道這個欄位是什麼。


錯誤訊息的出現時機

最常見的錯誤:使用者按送出才一次顯示所有錯誤。使用者要往回捲、一個個修、再送出,挫折感很高。

三種時機的取捨:

時機觸發條件適用場景
on blur欄位失焦時驗證大多數欄位的預設選擇
on change輸入中即時驗證密碼強度、即時搜尋
on submit按送出才驗證只在前兩個都沒辦法用時
<!-- 錯誤訊息要放在欄位附近,用 aria-describedby 關聯 -->
<div>
  <label for="email">Email</label>
  <input
    type="email"
    id="email"
    name="email"
    aria-describedby="email-error"
    aria-invalid="true"
  >
  <span id="email-error" role="alert">請輸入有效的 Email 格式</span>
</div>

aria-invalid="true" 讓螢幕閱讀器知道這個欄位有錯;role="alert" 讓錯誤訊息出現時立即朗讀。

錯誤訊息的文字原則:

  • ❌「格式錯誤」(說了等於沒說)
  • ❌「Invalid input」(沒說哪裡錯)
  • ✅「請輸入 email 格式,例如 name@example.com」(說清楚正確格式)

Tab order:鍵盤使用者的移動路線

Tab 鍵在欄位間跳轉的順序預設跟 DOM 順序一致。不要用 tabindex 強制改順序——這幾乎總是代表 HTML 結構需要調整。

<!-- ❌ 用正數 tabindex 強制排序,會打亂螢幕閱讀器和鍵盤使用者 -->
<input tabindex="3" name="last-name">
<input tabindex="1" name="first-name">
<input tabindex="2" name="email">
 
<!-- ✅ 讓 DOM 順序就是正確順序 -->
<input name="first-name">
<input name="last-name">
<input name="email">

tabindex="0" 是讓原本不可聚焦的元素(<div><span>)加入 tab 順序,有時候必要。tabindex="-1" 是讓元素可以用 JS 的 .focus() 聚焦但不在 tab 順序裡(modal 開啟時自動聚焦用)。


行動裝置鍵盤優化

除了前一篇說的 type 屬性,還有幾個屬性影響行動裝置體驗:

<!-- inputmode:不換 type 但改鍵盤 -->
<!-- 身分證號是文字但要數字鍵盤 -->
<input type="text" name="id-number" inputmode="numeric" pattern="[0-9]*">
 
<!-- 小數點數字 -->
<input type="text" name="price" inputmode="decimal">
 
<!-- 搜尋(鍵盤右下角顯示搜尋鍵) -->
<input type="search" inputmode="search">
 
<!-- enterkeyhint:enter 鍵顯示什麼文字 -->
<input type="text" enterkeyhint="next">    <!-- 下一步 -->
<input type="text" enterkeyhint="done">    <!-- 完成 -->
<input type="text" enterkeyhint="search">  <!-- 搜尋 -->
<input type="text" enterkeyhint="go">      <!-- 前往 -->

inputmodetype 更細緻——你可以保留 type="text"(不觸發瀏覽器格式驗證),但用 inputmode="numeric" 讓行動裝置彈出數字鍵盤。


必填欄位的正確標示

<!-- ✅ HTML required + 視覺標示 + aria -->
<label for="email">
  Email
  <span aria-hidden="true">*</span>
  <span class="sr-only">(必填)</span>
</label>
<input type="email" id="email" name="email" required aria-required="true">
 
<!-- 表單頂端說明星號意思 -->
<p><span aria-hidden="true">*</span> 標示為必填欄位</p>

aria-hidden="true" 讓螢幕閱讀器忽略視覺上的 *,改讀旁邊的「(必填)」文字,避免使用者聽到「Email 星號」這種奇怪的朗讀。


相關文章