Day 11|表單錯了,怎麼帶人修回來?從 Label 到 Validation Summary 的修正路徑
2026 iThome 鐵人賽 Vibe Coding UI Day 11:安安~我是ChiYu~ 昨天,三份附件終於可以各自上傳、失敗與重試。我把活動名稱留空、Email 填錯,再按下「發布」,整份表單卻只亮起幾個紅框。 為了排除活動頁自己的問題,我又把前幾天完成的「新增成員」表單抓回來重測。原始需求同樣…
快速導覽 查看本文目錄
本文同步自 2026 iThome 鐵人賽原文 。完整系列可見 iThome 系列頁 。
安安~我是ChiYu~
昨天,三份附件終於可以各自上傳、失敗與重試。我把活動名稱留空、Email 填錯,再按下「發布」,整份表單卻只亮起幾個紅框。
為了排除活動頁自己的問題,我又把前幾天完成的「新增成員」表單抓回來重測。原始需求同樣很簡短:
幫我做一個新增成員表單,必填欄位錯了要顯示紅色。
下面是依這句 Prompt 還原的第一版問題現場:

圖 1:姓名留空、Email 格式錯誤、登入帳號太短,三個欄位卻只剩紅色外框可以辨認。
AI 的確把姓名、Email、登入帳號、Checkbox 和送出按鈕做了出來。送出失敗後再把邊框改成紅色,也完全符合我的要求。
然後就沒有然後了。
三個紅框很認真地告訴我「你填錯了」,卻沒有任何一個願意說先修哪裡、錯在什麼地方。顏色只能指出「這附近有事」,沒辦法回答哪一條規則沒通過、格式怎麼改,或整份表單還有幾個問題。
這次我要補的不是更醒目的紅色,而是一條修正路徑:使用者在輸入前看得懂規則,欄位出錯時知道怎麼改,送出失敗後也能回到正確位置。
我把這條路整理在 表單結構與驗證完整比較頁 :

圖 2:欄位名稱、填寫規則、單欄錯誤與整份表單摘要,各自在不同時機接手。
表單驗證不是一張紅色濾鏡,而是三段修正路徑
先不背八種術語,我會把表單分成三個位置:
| 資訊出現的位置 | 要回答的問題 | 相關元件或結構 |
|---|---|---|
| 輸入以前 | 這欄要填什麼?格式、用途與必填規則是什麼? | Label、Helper Text、Required Indicator、Fieldset、Legend |
| 問題欄位旁 | 現在哪裡不對?要怎麼改? | Inline Validation、Error Message |
| 送出失敗後的表單前方 | 一共有幾個問題?我要先回到哪裡? | Validation Summary |
這三段不能互相代班。頁首摘要可以告訴我有兩個問題,卻不該取代 Email 欄位旁的具體修法;紅框放得再多,也不能補回一開始沒寫的填寫規則。
輸入以前:Label、說明與必填規則先把題目講清楚
Label 填完後也不能跟著消失
Label|欄位標籤 是欄位一直看得到的名字。像「成員姓名」與「公司 Email」,內容填進去後,Label 仍要留在畫面上。

圖 3:Label 與輸入框維持可見關係,欄位有內容時仍知道自己正在編輯什麼。
Placeholder 會在輸入後消失,不能代替 Label。W3C 建議使用 <label>,以相同的 for 與 id 連結輸入欄;輔助科技能辨識欄位,點擊文字也會把焦點帶進控制項。
W3C WAI:Labeling Controls
Helper Text 在出錯前先公布規則
Helper Text|輔助文字 補充「怎麼填」或「為什麼要填」。公司 Email 下方可以先寫:「請輸入工作用 Email,邀請信會寄到這裡。」

圖 4:Helper Text 在輸入前交代 Email 用途與規則,不必等送出失敗才公布答案。
Helper Text 可以用 aria-describedby 與欄位建立關聯。它負責補規則,仍然不能兼差當欄位名稱。
MDN:aria-describedby
Required Indicator 不能只剩一顆紅色星號
Required Indicator|必填標記
告訴使用者哪些資料一定要有。星號可以使用,前提是表單先說明星號代表必填,控制項本身也有 required 規則。

圖 5:必填規則同時有可見標記與欄位語意,不能只靠紅色猜意思。
如果必填的是一組 Checkbox 或 Radio,規則應放在整組的共同題目附近,不要讓每個選項各自長出一顆星號。 W3C WAI:Validating Input
一組選項共同回答一題,就用 Fieldset 與 Legend 把關係留下來
LumenDesk 的 Email、站內通知與每週摘要共同回答「你想收到哪些通知?」它們不是三個剛好排在一起的 Checkbox。
Fieldset|欄位群組 負責建立群組結構, Legend|群組標題 則替這一組命名共同問題。

圖 6:Fieldset 把通知選項建立成一組,讓視覺排列與表單語意一致。

圖 7:Legend 替通知群組命名;每個 Checkbox 仍保留自己的 Label。
只放一個粗體小標,視覺上可能差不多,輔助科技得到的群組脈絡卻不同。Legend 也不能取代單一選項的 Label;先有共同問題,才需要這組結構。
這裡的「每週摘要」指可獨立訂閱的通知內容,因此能和 Email、站內通知並列。需求若改成「每天、每週或每月寄一次」,那是在選頻率,一次只能留一個答案,應該改用 Radio。排得整齊不會自動修正資料關係。
W3C 的表單教學也建議用 <fieldset> 與 <legend> 組織相關控制項,並讓 Legend 保持簡短。
W3C WAI:Grouping Controls
欄位旁:能判斷時再回饋,錯了就直接告訴我怎麼修
Inline Validation 不要在使用者剛進欄位時搶答
Inline Validation|即時驗證 適合在規則已經能判斷時提早回饋。登入帳號至少 4 個字元,可以等使用者離開欄位,或輸入已達可判斷長度後再檢查。

圖 8:Inline Validation 等到規則可判斷才回饋,初始空欄位不會先亮錯誤。
使用者剛 Tab 進空欄位,畫面就跳出「至少 4 個字元」,技術上很即時,操作上比較像搶答。初始狀態先保持安靜;真的輸入不足、含有不允許字元,或離開欄位後,再把規則說清楚。
Error Message 保留原值,也要說出修法
Error Message|錯誤訊息 應留在問題欄位旁,保留使用者原本的輸入,再說明錯誤原因與修正方式。

圖 9:錯誤的 Email 留在欄位中,訊息直接提供含有 @ 的格式範例。
「格式錯誤」仍然太省話。這裡會寫成:「請輸入含有 @ 的公司 Email,例如 [email protected]
。」W3C 也建議以 aria-invalid 標示錯誤欄位,並把錯誤訊息與欄位建立關聯。
W3C:ARIA21
送出失敗後:摘要負責定位,欄位旁訊息負責修正
Validation Summary|驗證摘要 在送出失敗後出場。它放在表單前方,列出錯誤數量、欄位名稱、原因與頁內連結。

圖 10:Validation Summary 列出兩個問題並提供頁內連結,欄位旁仍保留各自修法。
我沒有先填資料,直接按下「建立成員」。頁首出現「請修正 2 個欄位」,列出:
- 成員姓名:此欄位必填。
- 公司 Email:請輸入含有
@的格式。
兩個欄位旁仍保留各自的錯誤訊息,焦點則回到第一個姓名欄位。接著我點摘要裡的「公司 Email」,焦點回到 Email 欄位;修正姓名與 Email 後,舊錯誤和摘要一起收起,其他已填入的非敏感資料也沒有被清空。
我接受這個結果,不是因為紅框比較醒目,而是整條路走得回去:摘要先交代有幾個問題,頁內連結負責定位,欄位旁訊息繼續提供修法,焦點也真的回到可以動手修改的位置。
焦點先停在摘要,還是直接回到第一個錯誤,沒有一套適合所有表單。LumenDesk 這次選擇「宣告錯誤總數後,把焦點移到第一個錯誤欄位」,摘要連結仍可前往其他欄位。這是本案例的可驗收策略,不是唯一標準。
W3C 也建議在表單前列出錯誤,讓每一項引用對應欄位、說明修正方式並提供頁內連結;欄位附近則保留更具體的回饋。 W3C WAI:User Notification
把八種資訊放回表單,它們其實只在三個位置接力

圖 11:Label 與規則在輸入前出現;欄位錯誤留在旁邊;多個問題則由頁首摘要協助定位。
Label、Helper Text 與必填規則先把題目說清楚;Fieldset 與 Legend 保留選項群組;Inline Validation 和 Error Message 在欄位可判斷時接手;多個問題同時出現,才由 Validation Summary 幫忙定位。
看起來像八種元件,真正要守住的只有三件事:規則先說、錯誤就近、送出失敗後找得到回去的路。
改寫 Prompt:把「顯示紅色」改成一條修正路徑
為 LumenDesk 建立「新增成員」表單,包含成員姓名、公司 Email、登入帳號與通知管道。
每個欄位都要有可見 Label,不能以 Placeholder 取代。成員姓名與公司 Email 為必填;以可理解的「必填」文字或已說明的標記呈現,控制項本身使用 required。表單開頭說明必填標記的意思。
公司 Email 下方提供 Helper Text:「請輸入工作用 Email,邀請信會寄到這裡。」使用 aria-describedby 關聯說明。Email 格式錯誤時保留輸入,設定 aria-invalid,並在欄位附近顯示「請輸入含有 @ 的公司 Email,例如 [email protected]」。不要只畫紅色外框。
通知管道的 Email、站內通知與每週摘要放在同一個 Fieldset;Legend 使用「你想收到哪些通知?」。若整組必填,把規則寫在 Legend 或群組附近,不要讓每個選項各自冒出必填星號。
登入帳號可使用 Inline Validation,但初始空欄位不顯示錯誤。使用者離開欄位,或輸入已達可判斷長度後,才回饋至少 4 個字元、可使用英文字母、數字與連字號的規則;成功和錯誤都要有文字。
送出失敗時,在表單前顯示 Validation Summary,列出錯誤數量、欄位名稱、具體原因與頁內連結,並以動態訊息宣告錯誤總數。這個 Demo 顯示摘要後,把鍵盤焦點移到第一個錯誤欄位;點擊摘要連結時,則把焦點帶到對應欄位。摘要不能取代欄位旁的錯誤訊息。所有欄位需保留使用者已輸入的非敏感資料。
交付前,我會再跑一次完整路線:先送出空白表單,再填錯 Email、留空另一個必填欄位,接著從摘要點回欄位修正。舊錯誤要在修正後消失,沒有問題時摘要也要收起。
表單走得回完成,內容工具又一次全員到齊
現在,空白送出會先列出兩個問題;點擊「公司 Email」能回到欄位,旁邊保留具體修法,其他已填資料也不會消失。原本只會亮紅框的畫面,終於知道怎麼把人帶回完成。
接著 AI 提出要讓內容管理「更完整」:六格驗證碼、標籤膠囊、色盤和整排編輯工具一次全上。功能看起來很多,管理員是不是真的需要,又是另一回事。

圖 12:六格驗證碼、標籤膠囊、完整色盤與大型 Editor 同時出現;畫面沒有先回答哪些工作真的需要這些控制。
明天,我不會急著全部收下。我會先把這些進階輸入元件拿掉,看看管理員的工作到底有沒有變難。
延伸閱讀
- W3C WAI:Labeling Controls
- W3C WAI:Validating Input
- W3C WAI:Grouping Controls
- W3C WAI:User Notification
- W3C:ARIA21—使用
aria-invalid指出欄位錯誤 - MDN:
aria-describedby
資料查閱:2026-08-07。
留言討論
用 GitHub 帳號留言,留言會同步到這個 Blog 的 GitHub Discussions。