Forms

大多數的網站和應用程式都包含網路表單。笑話網站,例如 DoWebsitesNeedToLookExactlyTheTheOfEveryBrowser.com, 可能沒有表單,甚至是 MachineLearningWorkshop.com (MLW),最初是愚人節的笑話, 就是假的MLW 的主要「行動號召」是報名研討會的註冊表單。這份表單 包含在 <form> 元素中。

HTML <form> 元素識別的是含有地標的文件 互動式控制項,以便提交資訊。在 <form> 的巢狀結構內,您可以找到所有互動式 (非互動式) 內容 構成表單的控制項

HTML 很強大。本節將著重介紹 HTML 的功能,說明無需加入 JavaScript 即可操作 HTML 的功能。 以某種方式透過用戶端使用表單資料更新 UI 的做法通常涉及 CSS 或 JavaScript,但本文並未討論這個部分。 這堂「學習表單」課程分成了整堂。我們不會在這裡重複這個部分,但會在稍後介紹 一些表單控制項以及賦予這些控制項的 HTML 屬性。

有了表單,使用者就能與網站或應用程式互動、驗證輸入的資訊,然後提交 將資料傳送至伺服器HTML 屬性可以要求使用者選取表單控制項或輸入值。HTML 屬性可以定義特定條件,而值必須符合這些條件才算有效。使用者嘗試提交表單時 所有表單控制項值都會經過用戶端限制驗證,可能導致無法提交 直到資料符合必要條件都不需要 JavaScript你也可以關閉這項功能:透過設定novalidate <form> 屬性 (或更常用於按鈕的 formnovalidate) 來儲存表單資料供日後使用。 禁止驗證。

提交表單

當使用者啟用表單內的提交按鈕時,即可提交表單。針對按鈕使用 <input> 時, 「value」是按鈕的標籤,會顯示在按鈕中。使用 <button> 時,標籤是兩個起始點之間的文字 和結尾 <button> 標記。提交按鈕的方法有兩種:

<input type="submit" value="Submit Form">
<button type="submit">Submit Form</button>

如果是簡單的表單,您需要一個 <form> 元素,其中含有一些表單輸入內容,另一個則是提交按鈕。不過 提交表單的頻率更高。

<form> 元素的屬性會將 HTTP 方法設為 表單提交狀態和處理表單提交的網址。可以,使用者可以提交、處理表單 新網頁不需任何 JavaScript 就能載入<form> 元素功能強大。

<form> 元素的 actionmethod 屬性值會定義用來處理表單資料的網址,以及用於提交資料的 HTTP 方法。 根據預設,表單資料會傳送至目前的網頁。否則,請將 action 屬性設為資料的傳送目標網址。

傳送的資料是由表單各種表單控制項的名稱/值組合組成。根據預設,這包括所有表單 以巢狀方式嵌入包含 name 的控制項。但是,使用 form 屬性即可加入表單控制項 在 <form> 之外,且要省略巢狀結構在 <form> 中的表單控制項。支援表單控制項和 <fieldset>form 屬性的值是相關聯的控制項 id 格式,不一定是該控制項的格式 巢狀結構中這表示表單控制項不需實際以巢狀結構嵌入 <form> 中。

method 屬性定義了要求的 HTTP 通訊協定:一般為 GETPOST。使用 GET 時,表單資料會以 name=value 組合的參數字串,附加至 action 的網址。

使用 POST 時,資料會附加至 HTTP 要求的主體。傳送安全資料 (例如密碼和信用卡) 資訊,請一律使用 POST

另有 DIALOG 方法。如果 <form method="dialog"> 位於 <dialog> 內,提交表單會關閉對話方塊。 表示如果未清除或提交資料,即為提交事件。同樣地,不使用 JavaScript。這在 對話方塊區段。提醒你,由於這無法提交表單,建議你 在提交按鈕中加入 formmethod="dialog"formnovalidate

表單按鈕可以包含比本節開頭說明的屬性更廣泛的屬性。如果按鈕包含 formactionformenctypeformmethodformnovalidateformtarget 屬性,用來在啟用表單的按鈕上設定的值 提交內容的優先順序高於 actionenctypemethodtarget <form>。限制驗證會在表單提交前進行,但前提是 已啟用的提交按鈕上的 formnovalidate,或 <form> 上的 novalidate

如要擷取使用者提交表單時使用的按鈕,請提供 name 按鈕。沒有名稱或值的按鈕,不會隨表單提交時一併傳送。

提交表單後

使用者提交填妥的線上表單時,系統會提交相關表單控制項的名稱和值。名稱是 name 屬性的值。這些值來自 value 屬性的內容,或是使用者輸入或選擇的值。<textarea> 的值是其內部文字。 <select> 的值是所選 <option>value,如果 <option> 不包含 value 屬性,則值會是所選選項的內部文字。

<form method="GET">
  <label for="student">Pick a student:</label>
  <select name="student" id="student">
    <option value="hoover">Hoover Sukhdeep</option>
    <option>Blendan Smooth</option>
    <option value="toasty">Toasty McToastface</option>
  </select>
  <input type="submit" value="Submit Form">
</form>

選取「Hoover Sukhdeep」(或者不執行任何動作,當瀏覽器顯示時,就會預設選取第一個選項值) 接著按一下提交按鈕,系統就會重新載入這個網頁,並將網址設為:

https://web.dev/learn/html/forms?student=hoover

由於第二個選項沒有 value 屬性,因此內部文字會提交為值。選取「Blendan Smooth」 然後按一下提交按鈕,系統就會重新載入這個網頁,並將網址設為:

https://web.dev/learn/html/forms?student=Blendan+Smooth

提交表單後,傳送的資訊會包含所有具有 name 的已命名表單控制項的名稱和值 包括未勾選的核取方塊、未選取的圓形按鈕,以及除了該按鈕以外其他任何按鈕的名稱和值 提交表單。如果是其他表單控制項,如果表單控制項含有名稱,但沒有輸入值或設為預設值,則 表單控制項的 name 提交時為空白值。

共有 22 種輸入類型,因此不涵蓋全部類型。 請注意,加入值是選擇性欄位,但往往不利於使用者輸入資訊。 對於使用者無法編輯值的 <input> 元素,建議您一律加入值,包括輸入 類型為 hiddenradiocheckboxsubmitbuttonreset 的元素。

為表單控制項使用專屬的 name 可簡化伺服器端資料處理,而且建議您採用核取方塊和 圓形按鈕是此規則例外。

圓形按鈕

如果您注意到,在一組圓形按鈕群組中選取圓形按鈕時,只有在 這是因為 name 屬性造成的。透過點選每個圓形按鈕,即可選搭一次可選的效果 加入同一個 name 的群組。

name 應專屬於群組:如果您不小心對兩個不同的群組使用相同的 name,請選取一個圓形按鈕 按鈕,就會取消選取第一個群組具有相同 name 的所選項目。

所選圓形按鈕的 name 和所選圓形按鈕的 value 已隨表單提交。請確保每個圓形按鈕 相關 (且通常不重複) 的 value。系統不會傳送未選取的圓形按鈕的值。

你可以在單一頁面上擁有不限數量的圓形按鈕群組,只要每個群組都有專屬的圓形按鈕群組, 專屬群組 name

如要利用已選取相同名稱群組中的其中一個圓形按鈕載入頁面,請加入 checked 屬性。 這個圓形按鈕將與 :default CSS 虛擬類別相符 即使使用者選取不同電台目前選取的圓形按鈕與:checked相符 虛擬類別

如果使用者需要從一組圓形按鈕群組中挑選圓形按鈕控制項,請將 required 屬性加入至少一個圓形按鈕 控制項如果將 required 加入群組的圓形按鈕,就會需要選取表單提交項目 不一定要是無線電中獲選的屬性此外,請在 <legend> 中清楚註明 必須使用表單控制項。我們會說明如何為圓形按鈕群組,以及每個個別按鈕加上標籤 我們稍後將在課程 深入介紹這些原則及擬定過程

核取方塊

這麼做可以確保群組中的所有核取方塊具有相同的 name。只有勾選的核取方塊會有namevalue 隨表單提交如果您選取了多個同名核取方塊,系統會將相同的名稱提交 (可能) 不同的價值。如果多個表單控制項使用相同的名稱,即使不是所有核取方塊也無妨 這樣所有查詢都會提交,並以連接號分隔。

如果沒有在核取方塊中加入 value,則所選核取方塊的值將預設為 on,但可能不是 很有幫助。如有三個名為「chk」的核取方塊,且這些核取方塊皆已勾選,則無法剖析表單提交內容:

https://web.dev/learn/html/forms?chk=on&chk=on&chk=on

如要強制勾選核取方塊,請加入 required 屬性。一律在必須勾選核取方塊時通知使用者,或在出現這類情形時通知使用者 適用任何表單控制項在核取方塊中新增 required 只會使該核取方塊變成必要核取方塊。不會影響其他 核取方塊。

標籤和領域

為了讓使用者瞭解如何填寫表單,表單必須可供存取。每個表單控制項都必須加上標籤。 您也想為表單控制項群組加上標籤。個別輸入內容、選取項目和文字區域都會加上 <label> 標籤。 表單控制項群組是以 <legend> 的內容加上標籤 用來分組的 <fieldset>

您可能已註意到,在上述範例中,提交按鈕以外的每個表單控制項都有 <label>。標籤 提供具有無障礙名稱的表單控制項。按鈕會從其內容或值中取得無障礙元素名稱。所有其他 表單控制項需要相關聯的 <label>。如果沒有相關聯的標籤,瀏覽器仍會顯示表單控制項, 但使用者不知道自己該提供哪些資訊。

如要將表單控制項與 <label> 明確建立關聯,請在 <label> 中加入 for 屬性:這個值會是 id 相關聯的表單控制項。

<label for="full_name">Your name</label>
<input type="text" id="full_name" name="name">

將標籤與表單控制項建立關聯有許多優點。標籤能讓螢幕閱讀器使用者存取表單控制項 為控制項提供可存取的名稱標籤也是「熱門區域」讓擁有電腦使用者 可以擴大範圍來解決小問題。如果你使用的是滑鼠,請嘗試點選「你的名稱」標籤的任一處。執行 所以會聚焦於輸入內容

如要提供隱含標籤,請在開頭和結尾 <label> 標記之間加入表單控制項。等於 可透過螢幕閱讀器和指標裝置視角存取,但並未提供一般的樣式連結 標籤。

<label>Your name
  <input type="text" name="name">
</label>

由於標籤是「命中區域」,因此請勿在明確的標籤中加入互動元素,或任何其他互動元件 。比方說,您在標籤中加入連結時 轉譯 HTML 程式碼時,如果使用者按一下標籤進入表單控制項,但系統重新導向至 新網頁

一般來說,<label> 會顯示在表單控制項之前,但圓形按鈕和核取方塊的情況除外。這不是必要步驟。 這只是常見的使用者體驗模式。「學習表單」系列提供表單設計相關資訊

對於圓形按鈕群組和核取方塊群組,標籤會提供相關聯表單控制項的無障礙名稱; 但控制項群組及其標籤也需要標籤如要為群組加上標籤,請將所有元素歸入同一個群組, <fieldset>,其中 <legend> 提供群組標籤。

<fieldset>
  <legend>Who is your favorite student?</legend>
  <ul>
    <li>
      <label>
        <input type="radio" value="blendan" name="machine"> Blendan Smooth
      </label>
    </li>
    <li>
      <label>
        <input type="radio" value="hoover" name="machine"> Hoover Sukhdeep
      </label>
    </li>
    <li>
      <label>
        <input type="radio" value="toasty" name="machine"> Toasty McToastface
      </label>
    </li>
  </ul>
</fieldset>

在這個範例中,隱含 <label> 會為每個標籤提供一個圓形按鈕,而 <legend> 則為圓形按鈕群組的標籤。 在另一個 <fieldset> 內建立巢狀結構的 <fieldset> 屬於標準做法。舉例來說,假設表單是針對許多問題回答的問題 分成數個相關問題,也就是「最愛學生」<fieldset> 可能以巢狀方式嵌入另一個 <fieldset> 中,並標示為 「你的最愛」:

<fieldset>
  <legend>Your favorites:</legend>
  <ul start="6">
    <li>
      <fieldset>
        <legend>Who is your favorite student?</legend>
        <ul>
          <li>
            <!-- the rest of the code here -->

這些元素預設外觀導致過度使用,但 <legend><fieldset> 可使用 CSS 設定樣式。 除了所有全域屬性外,<fieldset> 也支援 namedisabledform 屬性。 當您停用欄位集時,系統會停用所有巢狀表單控制項。nameform 屬性都不存在 在 <fieldset> 上取得了許多幫助。name 可用來透過 JavaScript 存取欄位集,但欄位集本身 未包含在提交的資料中 (包含在巢狀結構中的已命名表單控制項)。

輸入類型和動態鍵盤

如前所述,有 22 種輸入類型。 在某些情況下,當使用者的裝置配有動態鍵盤,而這類鍵盤只會在需要的情況下顯示 (例如手機),輸入的輸入內容。 使用的類型會決定系統顯示的鍵盤類型。預設鍵盤可以根據所需的輸入類型進行最佳化調整。 例如,輸入 tel 可顯示適合輸入電話號碼的撥號鍵盤。email 包含 @.;和 url 的動態鍵盤包含冒號和斜線符號。很抱歉,iPhone 仍不提供 : url 輸入類型的預設動態鍵盤。

<input type="tel"> 適用於 iPhone 和兩個不同 Android 手機的鍵盤:

iPhone 鍵盤顯示 input type=tel。 Android 鍵盤顯示 input type=tel。 Android 鍵盤顯示 input type=tel。

<input type="email"> 適用於 iPhone 和兩個不同 Android 手機的鍵盤:

iPhone 鍵盤顯示 input type=email。 Android 鍵盤顯示 input type=email。 Android 鍵盤顯示 input type=email。

存取麥克風和攝影機

<input type="file"> 檔案輸入類型支援透過表單上傳檔案。檔案可以是任何類型、定義或受限的 accept 屬性。可接受的檔案類型清單包括副檔名、全域的類型、 或全域類型和擴充功能的組合舉例來說,accept="video/*, .gif" 接受任何影片檔案或動畫 GIF。 使用「audio/*」對於音檔,「video/*」影片檔案和「image/*」圖片檔案

列舉的 capture 屬性 (定義於 媒體擷取規格,適用於新媒體 要透過使用者的相機或麥克風建立檔案。您可以將面向使用者輸入裝置的值設為 userenvironment 用於手機的後置鏡頭或麥克風。一般來說,在沒有值的情況下使用 capture 才能正常運作,因為使用者 則要選擇要使用的輸入裝置

<label for="avatar">A recent photo of yourself:</label>
<input type="file" capture="user" accept="image/*" name="avatar" id="avatar">

內建驗證功能

同樣,在未加入任何 JavaScript 的情況下,HTML 可能導致無法提交含有無效值的表單。

部分 CSS 選取器會根據是否出現 HTML 屬性 (包括 :required),比對表單控制項 和 :optional (表示布林值 required) 是否設定;:default表示checked 都是硬式編碼和 :enabled:disabled, 取決於元素是否互動,以及 disabled 屬性。:read-write 虛擬類別會比對具有 已設定 contenteditable 表單控制項預設為可編輯,例如 numberpasswordtext 輸入類型 (但無法勾選 圓形按鈕或 hidden 類型等)。如果一般可寫入的元素具有 readonly 屬性就會改為與 :read-only 相符。

當使用者在表單控制項中輸入資訊時,CSS UI 選取器,包括 :valid:invalid:in-range:out-of-range 將根據狀態切換為開啟或關閉。當使用者 結束表單控制項,可能是尚未完全支援的 :user-invalid:user-valid 虛擬類別將會比對。

使用者與表單互動時,您可以透過 CSS 提供提示,說明表單控制項是否必要且有效。 您還可以使用 CSS,防止使用者在表單有效前無法點選提交按鈕:

form:invalid [type="submit"] {
  opacity: 50%;
  pointer-events: none;
}

這個 CSS 程式碼片段屬於反模式。您的使用者介面可能讓人覺得直覺易懂,但許多使用者會嘗試提交表單, 啟用錯誤訊息。以這種方式顯示提交按鈕不會通過驗證限制驗證, 功能相當強大

系統會根據 UI 目前的狀態持續更新已套用的 CSS。舉例來說,如果您納入含有 限制,例如 emailnumberurl 和日期類型 (如果值並非空值 (非空白) 和目前的值) 值不是有效的電子郵件、數字、網址、日期或時間,系統將比對 :invalid CSS 虛擬類別。這個常數 更新與內建 HTML 限制驗證功能不同,後者只會在使用者嘗試提交表單時執行。

內建限制驗證功能只適用於透過 HTML 屬性設定的限制。你可以根據 瀏覽器提供的 :required:valid/:invalid 虛擬類別,並根據錯誤 requiredpatternminmax,甚至是 type 屬性會在提交表單時執行。

這則錯誤訊息指出必須提供複選欄位。

如果嘗試提交表單時未選擇喜愛的學生身分,限制驗證會阻止系統提交表單 原因是 validityState.valueMissing 錯誤。

如果任一 validityState 屬性傳回 true,提交作業就會遭到封鎖,且瀏覽器顯示錯誤訊息 第一個不正確的表單控制項,讓焦點集中在第一個錯誤的表單控制項中當使用者啟用表單提交時,如果其中出現無效的值, 第一個無效的表單控制項會顯示錯誤訊息並收到焦點如果必要控制項未設定值, 數值超出範圍,或是值不符合 type 屬性規定的類型,表單就無法驗證, 且會顯示錯誤訊息

如果 number、日期或時間值低於設定的下限 min 或高於 max 最大值,則控制項會是 :out-of-range (和 :invalid),且 使用者會收到 valididityState.rangeUnderflow 的通知。 發生 validityState.rangeOverflow 錯誤時 試著提交表單如果值與 step 值 (無論是明確設定或預設為 1),控制項都是 :out-of-range (和 :invalid),且會有 validityState.stepMismatch 錯誤。錯誤會以泡泡形式顯示,且預設會提供實用資訊,協助您修正錯誤。

值的長度也有類似的屬性:minlengthmaxlength 屬性則會在發生錯誤時通知使用者 使用 validityState.tooLongvalidityState.tooShort提交時。 maxlength 也會禁止使用者輸入過多字元。

使用 maxlength 屬性可能會導致使用者體驗不佳。通常希望使用者能享有更好的體驗 可提供計數器的字元長度超出上限,而且可選擇採用 <output> 元素,並未與表單一併提交。 只要啟用這個選項,就能在輸出內容未超過允許的長度上限之前編輯文字。maxlength 可加到您的 HTML 中就跟先前討論過的一樣,不用 JavaScript 也能運作。接著在載入時 maxlength 屬性可用來在 JavaScript 中建立這個字元計數器。

部分輸入類型似乎有預設限制,但沒有。舉例來說,tel 輸入類型會提供數字 撥號鍵盤上的應用程式,但不會限制有效值。針對這個與其他輸入類型 其中包含 pattern 屬性。您可以指定會將值相符才視為有效的規則運算式。 如果值是空字串,且該值不是必要值,則不會產生 validityState.patternMismatch 錯誤。如果該必要欄位為空白,使用者會看到 validityState.valueMissing 的預設錯誤訊息,而非 patternMismatch

對於電子郵件,validityState.typeMismatch 可能也最為理想 滿足您的需求建議您納入 pattern 屬性,因此系統不會將沒有 TLD 的內部網路電子郵件地址視為有效。 模式屬性可讓您提供值必須符合的規則運算式。要求比對模式時 確保使用者清楚瞭解你的期望

這一切作業都不需要編寫一行 JavaScript,但如果是 HTML API,則可以使用 JavaScript 加入 限制期間的自訂訊息。您也可以使用 JavaScript 更新剩餘的字元數,顯示 密碼強度進度列,或任何其他動態改善輸入方式的方法。

範例

此範例在 <dialog> 內有一個表單,包含具巢狀結構的 <form>,其中包含三個表單控制項和兩個提交按鈕, 清除標籤和操作說明

第一個提交按鈕會關閉對話方塊。使用 formmethod="dialog" 覆寫表單的預設方法,然後關閉 <dialog>,且無須提交或清除資料。您還必須加入 formnovalidate,否則瀏覽器會 試著確認所有必填欄位是否都含有值。使用者可能想要關閉對話方塊和表單,而不需要 輸入任何資料;否則就會造成問題加入aria-label="close" (因為「X」)是已知的視覺提示 並非描述性標籤

表單控制項皆含有隱含標籤,因此您不必加入 idfor 屬性。輸入內容 具有必要屬性數字輸入欄位已明確設定 step,以展示 step 如何 包含。由於 step 預設為 1,因此可以省略這個屬性。

<select> 有預設值,因此不需要使用 required 屬性。請勿加入 value 屬性 每個選項的值都會預設為內部文字。

結尾的提交按鈕會將表單方法設為 POST。按下後,系統會檢查每個值的有效性。如果所有 值有效,表單資料將會提交、對話方塊會關閉,網頁可能會重新導向至 thankyou.php。 也就是動作網址如果遺漏任何值,或是數值步數不符或超出範圍, 螢幕上會顯示相關的瀏覽器定義錯誤訊息,系統將不會提交表單,且對話方塊也不會關閉。 您可以使用 validityState.setCustomValidity('message here') 自訂預設錯誤訊息 方法。請注意,如果您設定了自訂訊息,則訊息必須在所有內容都明確設為空白字串的情況下 有效,否則表單無法提交。

其他注意事項

上半部旨在協助使用者在表單中輸入正確資料。不錯 請務必提供指示和提示,避免使用者出錯。 雖然本節會說明單獨使用 HTML 提供驗證用戶端的方式,但驗證必須同時採用用戶端和 伺服器端代碼使用者可在填寫表單時以不突兀的方式進行驗證,例如加入 如果值正確,則勾號。不過,請勿在表單控制項完成前顯示錯誤訊息。如果使用者 是否會出錯,讓使用者知道錯誤的部分以及問題為何。

設計表單時,請務必考量並非所有人都屬於您。某位使用者 可能只有單一字母代表姓氏 (或完全無姓氏),可能沒有郵遞區號、包含三行街道地址 沒有街道地址他們可能正在瀏覽表單的翻譯版本。

表單控制項、標籤和錯誤訊息都應該以程式輔助方式顯示在畫面上,而且內容正確且有意義 以程式輔助方式與適當的表單元素或群組建立關聯。autocomplete 屬性,可用來加快表單填寫速度,並提高無障礙功能的無障礙程度。

HTML 提供所有工具,讓您可以存取基本表單控制項。表單元素或程序的互動性較高 以無障礙程度來說,需要以無障礙功能為考量,包括聚焦管理、設定及更新 ARIA 名稱、角色 並在必要時提供 ARIA 即時公告但如我們所學,光是 HTML,就能產生 進而實現無障礙目標和有效性,不必仰賴 ARIA 或 JavaScript。

隨堂測驗

測試您對表單的瞭解程度。

為何圓形按鈕必須合併至同一個群組?

全部放在欄位集內。
請再試一次。
並為所有屬性提供相同的 name 屬性值。
答對了!
並為所有屬性提供相同的 id 屬性值。
請再試一次。

哪一個 HTML 元素可用來向使用者說明這個表單欄位的功用?

<h1>
請再試一次。
<title>
請再試一次。
<label>
答對了!