安安~我是ChiYu~
昨天,三份附件終於可以各自上傳、失敗與重試。我把活動名稱留空、Email 填錯,再按下「發布」,整份表單卻只亮起幾個紅框。
為了排除活動頁自己的問題,我又把前幾天完成的「新增成員」表單抓回來重測。原始需求同樣很簡短:
幫我做一個新增成員表單,必填欄位錯了要顯示紅色。
下面是依這句 Prompt 還原的第一版問題現場:

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

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

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

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

圖 5:必填規則同時有可見標記與欄位語意,不能只靠紅色猜意思。
如果必填的是一組 Checkbox 或 Radio,規則應放在整組的共同題目附近,不要讓每個選項各自長出一顆星號。W3C WAI:Validating Input
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|即時驗證 適合在規則已經能判斷時提早回饋。登入帳號至少 4 個字元,可以等使用者離開欄位,或輸入已達可判斷長度後再檢查。

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

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

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

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

圖 12:六格驗證碼、標籤膠囊、完整色盤與大型 Editor 同時出現;畫面沒有先回答哪些工作真的需要這些控制。
明天,我不會急著全部收下。我會先把這些進階輸入元件拿掉,看看管理員的工作到底有沒有變難。
aria-invalid 指出欄位錯誤
aria-describedby
資料查閱:2026-08-07。