Like Share Discussion Bookmark Smile

J.J. Huang   2019-05-27   Web   瀏覽次數:

Web - 第十八章 | HTML 建構Form表單

HTML表單的靈活性使它們成為HTML中最複雜的結構之一; 你可以使用專用的表單元素和屬性構建任何類型的基本表單。在構建HTML表單時使用正確的結構將有助於確保表單既可用又可訪問。

<form>元素

<form>元素按照一定的格式定義了表單和確定表單行為的屬性。當你想要建立一個HTML表單時,都必須從這個元素開始,然後把所有內容都放在裡面。許多輔助技術或瀏覽器插件可以發現<form>元素並實現特殊的鉤子,使它們更易於使用。

注:嚴格禁止在一個表單內嵌套另一個表單。嵌套會使表單的行為不可預知,而這取決於正在使用的瀏覽器。

請注意,在

元素之外使用表單小部件是可能的,但是如果你這樣做了,那麼表單小部件與任何表單都沒有任何關係。這樣的小部件可以在表單之外使用,但是你應該對於這些小部件有特別的計劃,因為它們自己什麼也不做。你將不得不使用JavaScript定制他們的行為。

注:HTML5在HTML表單元素中引入form屬性。它讓你顯式地將元素與表單綁定在一起,即使元素不在

中。不幸的是,就目前而言,跨瀏覽器對這個特性的實現還不足以使用。

<fieldset>和<legend>元素

<fieldset>元素是一種方便的用於建立具有相同目的的小部件組的方式,出於樣式和語義目的。你可以在<fieldset>開口標籤後加上一個<legend>元素來給<fieldset>標上標籤。 <legend>的文本內容正式地描述<fieldset>的用途。它是包含在<fieldset>裡的。

許多輔助技術將使用<legend>元素,就好像它是相應的<fieldset>元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<form>
<fieldset>
<legend>Fruit juice size</legend>
<p>
<input type="radio" name="size" id="size_1" value="small">
<label for="size_1">Small</label>
</p>
<p>
<input type="radio" name="size" id="size_2" value="medium">
<label for="size_2">Medium</label>
</p>
<p>
<input type="radio" name="size" id="size_3" value="large">
<label for="size_3">Large</label>
</p>
</fieldset>
</form>

當閱讀上述表格時,屏幕閱讀器將會讀第一個小部件“Fruit juice size small”,“Fruit juice size medium”為第二個,“Fruit juice size large”為第三個。

本例中的用例是最重要的。每當你有一組單選按鈕時,你應該將它們嵌套在<fieldset>元素中。還有其他用例,一般來說,<fieldset>元素也可以用來對錶單進行分段。理想情況下,長表單應該在多個頁面之間進行拆分,但是如果表單很長,但必須在單個頁面上,那麼在不同的fieldsets中放置不同的相關部分可以提高可用性。

因為它對輔助技術的影響,<fieldset>元素是構建可訪問表單的關鍵元素之一。然而,你有責任不去濫用它。


<label>元素

<label>元素是為HTML表單小部件定義標籤的正式方法。如果你想構建可訪問的表單,這是最重要的元素——當正確實現時,屏幕閱讀器將會與任何相關的說明一起使用表單元素的標籤。

1
<label for="name">姓名:</label><input type='text' id="name">

通過他們各自的for 屬性和 id屬性,<label>標籤與<input>正確相關聯。如此,一個屏幕閱讀器會讀出諸如“Name, edit text”之類的東西。

如果標籤沒有正確設置,屏幕閱讀器只會讀出Edit text blank”之類的東西,這不太有幫助。

注意,一個小部件可以嵌套在它的<label>元素中

1
2
3
<label for="name">
Name: <input type="text" id="name">
</label>

儘管可以這樣做,但人們認為設置for屬性才是最好的做法,因為一些輔助技術不理解標籤和小部件之間的隱式關係。

標籤也可點擊

正確設置標籤的另一個好處是可以在所有瀏覽器中單擊標籤來激活相應的小部件。這對於像文本輸入這樣的例子很有用,在這裡你可以點擊標籤和輸入來聚焦它,它同樣對於單選按鈕和復選框特別有用——這種控件的可點擊區域可能非常小,設置標籤來使它們可點擊區域變大是非常有用的。

1
2
3
4
5
6
7
8
9
10
<form>
<p>
<label for="taste_1">I like cherry</label>
<input type="checkbox" id="taste_1" name="taste_cherry" value="1">
</p>
<p>
<label for="taste_2">I like banana</label>
<input type="checkbox" id="taste_2" name="taste_banana" value="2">
</p>
</form>

多個標籤

嚴格地說,你可以在一個小部件上放置多個標籤,但是這不是一個好主意,因為一些輔助技術可能難以處理它們。在多個標籤的情況下,你應該將一個小部件和它的標籤嵌套在一個<label>元素中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<p>Required fields are followed by <abbr title="required">*</abbr>.</p>

<!-- So this: -->
<div>
<label for="username">Name:</label>
<input type="text" name="username">
<label for="username"><abbr title="required">*</abbr></label>
</div>

<!-- would be better done like this: -->
<div>
<label for="username">
<span>Name:</span>
<input id="username" type="text" name="username">
<abbr title="required">*</abbr>
</label>
</div>

<!-- But this is probably best: -->
<div>
<label for="username">Name: <abbr title="required">*</abbr></label>
<input id="username" type="text" name="username">
</div>

頂部的段落定義了所需元素的規則。它必須在開始時確保像屏幕閱讀器這樣的輔助技術在用戶找到必需的元素之前顯示或念出它們。這樣,他們就知道星號是什麼意思了。根據屏幕閱讀器的設置,屏幕閱讀器會把星號讀為“star”或“required”——不管怎樣,都會在第一段中講清楚。

  • 在第一個例子中,標籤根本沒有和input一起被念出來——讀出來的只是“edit the blank”,和單獨被念出的標籤。多個
  • 在第二個例子中,事情變得清晰一點了——標籤和輸入一起,讀出的是“name star name edit text”,但標籤仍然是單獨讀出的。這還是有點令人困惑,但這次還是稍微好一點了,因為input和label聯繫起來了。
  • 第三個例子是最好的——標籤是一起讀出的,標籤和輸入讀出的是“name star edit text”。

注:你可能會得到一些不同的結果,這取決於你的屏幕閱讀器。


表單的通用HTML結構

除了特定於HTML表單的結構之外,還應該記住表單同樣是HTML。這意味著你可以使用HTML的所有強大功能來構造一個HTML表單。

正如你在示例中可以看到的,用<div>元素包裝標籤和它的小部件是很常見的做法。<p>元素也經常被使用,HTML列表也是如此(後者在構造多個複選框或單選按鈕時最為常見)。

除了<fieldset>元素之外,使用HTML標題(例如,<h1>、<h2>)和分段(如<section>)來構造一個複雜的表單也是一種常見的做法。

最重要的是,你要找到一種你覺得很舒服的風格,而且它也能帶來可訪問的、可用的形式。

它包含了<section>元素中包含的每個單獨的功能部分,以及一個<fieldset>來包含單選按鈕。

開始動手:

  1. 建立一個空白模板文件
  2. 添加<style>樣式
  3. 通過添加外部<form>元素來開始一張表單
  4. 在<form>標籤內,首先添加一個標題和段落,告訴用戶必需的字段是如何標記
  5. 我們將聯繫人訊息字段包裝在一個單獨的<section>元素中。此外,我們有一組兩個單選按鈕,每個單選按鈕都放在自己的列表中( <li>))元素。最後,我們有兩個標准文本<input>和它們相關的<label>元素,每個元素包含在<p>中,加上輸入密碼的密碼輸入。
  6. 我們將表單的第二個<section>——支付訊息。在這裡,我們有三個不同的小部件以及它們的標籤,每個都包含在一個<p>中。第一個是選擇信用卡類型的下拉菜單( <select>)。第二個是輸入一個信用卡號的類型編號的<input>元素。最後一個是輸入date類型的<input>元素,用來輸入卡片的過期日期(這將在支持瀏覽器中出現一個日期選擇器小部件,並在非支持的瀏覽器中回退到普通的文本輸入)。
  7. 我們要添加的最後一個部分要簡單得多,它只包含了一個submit類型的<button>,用於提交表單資料。
  • 空白模板

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <!DOCTYPE html>
    <html lang="en-US">
    <head>
    <meta charset="utf-8">
    <title>My test page</title>
    </head>
    <body>
    <p>This is my page</p>
    </body>
    </html>
  • css樣式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    h1 {
    margin-top: 0;
    }

    ul {
    margin: 0;
    padding: 0;
    list-style: none;
    }

    form {
    margin: 0 auto;
    width: 400px;
    padding: 1em;
    border: 1px solid #CCC;
    border-radius: 1em;
    }

    div+div {
    margin-top: 1em;
    }

    label span {
    display: inline-block;
    width: 120px;
    text-align: right;
    }

    input, textarea {
    font: 1em sans-serif;
    width: 250px;
    box-sizing: border-box;
    border: 1px solid #999;
    }

    input[type=checkbox], input[type=radio] {
    width: auto;
    border: none;
    }

    input:focus, textarea:focus {
    border-color: #000;
    }

    textarea {
    vertical-align: top;
    height: 5em;
    resize: vertical;
    }

    fieldset {
    width: 250px;
    box-sizing: border-box;
    margin-left: 136px;
    border: 1px solid #999;
    }

    button {
    margin: 20px 0 0 124px;
    }

    label {
    position: relative;
    }

    label em {
    position: absolute;
    right: 5px;
    top: 20px;
    }
  • body 內的 form 表單內容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    <form>
    <h1>Payment form</h1>
    <p>Required fields are followed by <strong><abbr title="required">*</abbr></strong>.</p>
    <section>
    <h2>Contact information</h2>
    <fieldset>
    <legend>Title</legend>
    <ul>
    <li>
    <label for="title_1">
    <input type="radio" id="title_1" name="title" value="M." >
    Mister
    </label>
    </li>
    <li>
    <label for="title_2">
    <input type="radio" id="title_2" name="title" value="Ms.">
    Miss
    </label>
    </li>
    </ul>
    </fieldset>
    <p>
    <label for="name">
    <span>Name: </span>
    <strong><abbr title="required">*</abbr></strong>
    </label>
    <input type="text" id="name" name="username">
    </p>
    <p>
    <label for="mail">
    <span>E-mail: </span>
    <strong><abbr title="required">*</abbr></strong>
    </label>
    <input type="email" id="mail" name="usermail">
    </p>
    <p>
    <label for="pwd">
    <span>Password: </span>
    <strong><abbr title="required">*</abbr></strong>
    </label>
    <input type="password" id="pwd" name="password">
    </p>
    </section>

    <section>
    <h2>Payment information</h2>
    <p>
    <label for="card">
    <span>Card type:</span>
    </label>
    <select id="card" name="usercard">
    <option value="visa">Visa</option>
    <option value="mc">Mastercard</option>
    <option value="amex">American Express</option>
    </select>
    </p>
    <p>
    <label for="number">
    <span>Card number:</span>
    <strong><abbr title="required">*</abbr></strong>
    </label>
    <input type="text" id="number" name="cardnumber">
    </p>
    <p>
    <label for="date">
    <span>Expiration date:</span>
    <strong><abbr title="required">*</abbr></strong>
    <em>formatted as mm/yy</em>
    </label>
    <input type="date" id="date" name="expiration">
    </p>
    </section>

    <p> <button type="submit">Validate the payment</button> </p>
    </form>

這邊轉載了大量的文章和內容,但是每個部分我都有實際去做過,並了解過。這邊轉載主要是做筆記記錄。

註:以上參考了
MDN web docsHow to structure an HTML form 文章。