表單

表單是值得拉一小節出來討論的,舉凡網路購物、問題回報、問卷回饋、登入等從開頭至結尾的種種行為,都需要使用到表單,至今仍是網路或應用程式中最重要的項目之一。

以下簡短介紹表單需要注意的重點。

需要標籤說明

  • 使用 <label>

    <label for="name">
        Name
        <input type="text" id="name">
    </label>
    <!-- 雖然包在裡面不用寫 for 就可以,但有些瀏覽器無法解析,所以還是建議加 for -->
    or
    
    <label for="name">Name</label>
    <input type="text" id="name">
    
  • 使用 aria-labelledby

    <span id="input-label">Your name</span>
    <input type="text" aria-labelledby="input-label">
  • 雖然可以使用,但有可能會不好傳達到,所以盡量不使用 aria-label

    <input type="search" aria-label="Search">

標籤必須簡短

如果需要解釋很多的時候,請使用 aria-labelledby 解釋,例如密碼的規則,不要將規則放到標籤裡。

關於三種隱藏

通常會因為設計師設計的畫面,可能會有以下三種情形:

  • 在畫面上隱藏,但還是可以報讀到 例如 Bootstrap 有提供 visually-hidden 和 visually-hidden-fucsable 兩個 classname (以前叫 sr-only)

  • 在畫面上顯示,但報讀隱藏 使用 html 的 aria-hidden="true"

  • 不在畫面上顯示,也不報讀,但是 DOM 想留著 display: none;

不要使用 placeholder

https://www.smashingmagazine.com/2018/06/placeholder-attribute/ 有以下結論

  • 無法自動翻譯;

  • 通常用來代替標籤,鎖定輔助技術;

  • 輸入內容時可以隱藏重要資訊;

  • 顏色可能太淺而難以辨認;

  • 造型選擇有限;

  • 可能看起來像是預先填寫的資訊並被跳過。

建議是將 placeholder 本來要呈現的資訊,全部往外顯示。

表單群組

分組可以讓相似的東西或有關聯的東西聚集在同一個地方,有助於理解表單內容。

可以使用 <fieldset> 和 <legend> 搭配,<fieldset> 本身就有 role="group"

<fieldset>
    <legend>XXX</legend>
 </fieldset>

如果要自定義,可以這樣使用:

<div role="group" aria-labelledby="theme_label">
    <h3 id="theme_label">XXX</h3>
    ...
</div>

確定輸入當下的情境與目的

確定目前正在輸入什麼,例如電話、電子郵件、數字等,可以參閱 https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/input

這樣的話,當使用者要輸入時,會有相對應的輸入外觀,以及在行動裝置上的虛擬鍵盤會顯示相對應的案件內容。

自動完成

可以參閱 https://developer.mozilla.org/zh-CN/docs/Web/HTML/Attributes/autocomplete

例如 one-time-code ,在行動裝置上可以顯示驗證碼,點擊之後就會自動填入,而不再需要輸入多位數的數字。

表單驗證

  • 提供必填提示

  • 提供輸入的正確規範

  • 提示哪一些輸入錯誤

  • 當輸入規範錯誤時,提供修正提示

Client-side

意味著在表單送進伺服器前,先對表單做檢查,檢查時機點

  • inline validation:填寫表單輸入框時

  • submit:送出表單時

兩種時機都會實作,在客戶端預先檢驗,可以提高使用者體驗,可以先修正錯誤,也避免送出等待後才知道錯誤。

以下為兩種方式實作:

  • Native Html5,但不推薦使用

    • 使用搭配原生 <form>,瀏覽器可根據 html 的限制給出錯誤提示

    • 並且 css 也可以使用 :valid, :invalid, user-valid, user-invalid

  • 客製化表單驗證 https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation#validating_forms_using_javascript

    • 必填與選填,怎麼才是最佳解?

      • 根據當下情況,給予使用者最便利、最不困惑為最佳,例如:

        • 如果表單內容已經精挑細選出必要欄位,且只有少數選填,那麼就特意標出選填資訊

        • 如果表單欄位眾多,且選填項也很多,那麼就可能需要標出必填

        • 但總的來說,標示清楚,是最基本的。

        • 如果要用常見的 * 當必填,必須在最前面就提醒使用者,但還是直接用文字寫出來比較好,因為報讀的時候,會將"star"報讀出來,所以為了避免報讀出"star",又需要多做其他處理,那不如直接將"必填"直接寫出來。例如使用 <abbr title="required"></abbr>,而且因為有些字體的*很小,有需要使用CSS將它放大。或是直接使用 aria-hidden 在報讀時隱藏,但另外提供報讀 required 的 DOM或 aria-required。

    • required or aria-required

      • 更多的是使用者體驗決定,因為有些瀏覽器在 required 時,可能在頁面一開始,使用者到達輸入框,就已經報讀出此欄位已經錯誤,但實際上使用者根本就還沒有動作,這造成了體驗上的困擾。

    • group required

      • 因為如果把 required 都放在各自的 radio 或 checkbox,聽起來像是每一個都必須選擇。 但是 <fieldset> 沒辦法加上 required ,然後 role="group" 也沒辦法加上 aria-required,所以必須根據內容改變 role 。例如如果內容是單選,那麼會改成: <fieldset role="radiogroup" aria-required="true">

    • 錯誤提示

      • 不要只使用單一辨識,例如只使用顏色辨識。

      • 如何修正錯誤?

      • 指出哪一欄位錯誤。

      • inline validation

        • 當使用者還未送出或還未取消焦點位置時,不要顯示錯誤。

          • 錯誤原因是什麼?可以使用 aria-describedby ,指到錯誤提示段落。

      • submit

        • 如果是結合 inline validation,必須跳到第一個發生錯誤的地方,並且提供提示文字和報讀狀態的變化。若是多個段落的群組,則焦點也是跳到第一個輸入的地方。

        • 如果沒有結合 inline validation,則應有摘要區域,使用 aria-describedby ,指到錯誤提示段落。摘要內必須有類似 table of content 的列表,點擊項目可以跳至相對應的輸入框。

    • 永遠不要禁用送出表單按鈕,除非您有做了詳細研究禁用對於您的使用者是好事。

      • 通常不會針對禁用的外觀調整,所以對比度很差

      • 禁用可能會讓報讀軟體跳過,從而導致不知道有沒有送出按鈕

      • 對理解能力相對較弱的群體,可能無法理解為什麼被禁用

    • 狀態更新 狀態更新也可以應用在網頁上任何會動態改變的地方,但盡量避免使用,使用時應確保這是使用者必須得知的資訊:

      • aria-live

        • assertive:狀態改變時,會打斷目前報讀,立即通知使用者。

          • polite:完成目前動作後才報讀。

      • role="alert"

        • 同 assertive,差別在於使用 alert 的是具有角色意涵的

      • 可以使用 <title> 說明此頁面狀況,因為 title 是報讀軟體在刷新頁面時最新報讀的。

      • aria-relevant:什麼樣的類型改變了就會報讀

        • additions:有 DOM 加入了

        • removals:有 DOM 刪除了

        • text:文字改變了

        • all:以上

      • aria-atomic

        • true:有任何一個地方改變了

        • false:預設值,只宣布該元素部分改變了

      • aria-busy:true 變成 false 的時候報讀

        • true:正在改變,例如 loading 時(有些情況會即時在輸入框旁載入)

        • false:預設值

      • <output> 標籤:等於 polite

        <label for="[ outputID ]">..</label>
        <output id="[ outputID ]"> .. </output>

小結

沒有一種最佳解可以適用任何情形!

表單應用的情況實在是太複雜,建議與使用者體驗研究員、使用者體驗分析師、UI 設計師一起討論當下使用者的情況以及業務流程,才能設置出最恰當的表單。

在常見問題裡,也有收錄簡短表單的問題,可前往閱讀

參考來源

Last updated