表單是HTML最主要的用戶輸入元素
用戶和網頁的交互動作有鼠標懸停、點擊鏈接(或移動觸摸)和頁面滾動等,這些交互方式一般只是服務器單向信息輸出。
有時候用戶需要輸入一些信息給服務器來完成雙向交互,這類交互包括:
- 注冊/登錄
- 用戶信息填寫
- 搜索/過濾
- 上傳文件
- 文章編輯
表單及其控件就是HTML用來支持上述交互的主要元素:
- 文本輸入(單行或多行)
- 單選框
- 多選框
- 下拉列表
- 文件上傳控件
- 表單提交按鈕
這些控件使用不同的HTML 標簽,但大部分使用 <input> 標簽,而使用 type 屬性來區別輸入控件的類型:
<!-- 文本輸入 --> <input type="text"> <!-- 復選框 --> <input type="checkbox"> <!-- 單選框 --> <input type="radio">
表單元素(form)
<form> 是塊級元素,用來定義網頁中的交互輸入部分。所有的表單控件必須包含在 <form> 元素中。
表單元素有兩個必須的屬性:
action用來定義信息提交的目標(即表單提交到哪里去)method用來定義信息提交的方式(即表單怎么提交),可以是 GET 或 POST 其中之一。
通常表單信息被提交給 action 所指定的服務器程序,服務器(即后端程序如PHP/Java)會對表單信息做出處理並給出應答。
表單用來把一組表單控件集中起來完成一個特定的交互操作,比如登錄表單,通常包含3個控件:
- 電子郵箱
<input type="email"> - 用戶密碼
<input type="password"> - 提交按鈕
<input type="submit">
這些控件被包含在一個 <form action="/login" method="POST"> 元素中。
文本輸入框
為了支持用戶輸入姓名,電子郵件,密碼,地址等信息,HTML表單中的文本輸入框控件包含多種類型:
| 普通文本 | <input type="text"> |
可以輸入任意字符 | |
|---|---|---|---|
| 電子郵件 | <input type="email"> |
如果輸入的是非法電子郵件,會出現告警提示 | |
| 密碼 | <input type="password"> |
顯示為小黑點,隱藏用戶輸入 | |
| 數字 | <input type="number"> |
只能輸入數字,且可以使用上下鍵來快速改變數值 | |
| 電話 | <input type="tel"> |
可以觸發自動填充 | |
| 多行文本 | <textarea></textarea> |
(注:復制原因顯示效果不完善,請自行測試,或查看底部原網址) | 可以調整文本輸入框的大小 |
盡管這些輸入框看起來很相似,且數據類型的默認校驗也不那么有效,似乎有點冗余,但從語義上來看,type 賦予了輸入框更具體的含義,這會有助於瀏覽器在實現這些控件接口時更好的提升用戶交互體驗。
占位符(Placeholders)
為了更好的提示用戶輸入,文本輸入框可以顯示占位符文本而不是空白,占位符在用戶開始輸入時會自動消失,不會形成干擾。
<input type="text" placeholder="請輸入昵稱">
試一下,當你開始輸入時,“請輸入昵稱” 會消失。
標簽(Labels)
由於表單控件本身不具備很好的自描述性,通常會在控件前面添加配對的文本標簽(label),對控件作用做出提示。
<label>Email</label> <input type="email">
對於純文本輸入框而言標簽(label)和占位符(placeholder)功能類似,不過標簽會一直顯示,且可以用於保持和其它表單元素對齊,比如選擇框。
盡管我們可以使用簡短的文本來描述表單控件,使用 <label> 在語義上要更符合規范,它們只用於表單內,還可以通過 for 屬性來和擁有特定 id 的輸入控件配對使用。
<label for="first_name">名字</label> <input id="first_name" type="text">
點擊標簽文本,輸入焦點會移動到文本輸入框內。這對於單選和復選框的操作尤為方便。
復選框(Checkboxes)
復選框 是選擇型控件,擁有兩個狀態:選中(checked)和未選中(unchecked)。一般用來接受用戶回答“是”或“否”。
<input type="checkbox"> 同意用戶協議
由於選擇框很小,點擊選中不方便,因此,比較好的實踐是在該元素外面包裹一個 <label> :
<label> <input type="checkbox"> 同意用戶協議 </label>
除了上面的方法,也可以使用label的 <for> 屬性來和input配對:
<input id="terms" type="checkbox"> <label for="terms">同意用戶協議</label>
這樣你就可以通過點擊 “同意用戶協議” 來切換復選框的選擇狀態。
默認情況下,復選框是未選中狀態,你可以簡單的通過設置 checked 屬性來改變狀態。
<label> <input type="checkbox" checked> 同意用戶協議 </label>
復選框還有一個重要的用途是可以讓用戶在一組可選項中進行多項選擇。
首先我們需要組合(group)一些復選框,為此我們為它們設置相同的 name 屬性:
<label>興趣</label> <input id="game" type="checkbox" name="interests"> <label for="game">電競</label> <input id="coding" type="checkbox" name="interests"> <label for="coding">編碼</label> <input id="rock" type="checkbox" name="interests"> <label for="rock">搖滾</label>
單選框(Radioboxes)
單選框用來給用戶在一組可選項中做單項選擇。
同上,我們通過為單選框設置相同的 name 屬性來把它們編組:
<label>婚姻狀態</label> <label> <input type="radio" name="status"> 單身 </label> <label> <input type="radio" name="status"> 已婚 </label> <label> <input type="radio" name="status"> 離異 </label>
由於我們把這組單選框的 name 屬性都設置成了相同的 "status",選擇其中一項,將導致其它選項被重置為未選中狀態。這就是單選框的互斥(mutually exclusive)特性。
單選框和復選框的差異
復選框可以只有一個,用於提示用戶回答是或否。而單個的單選框卻沒有意義,必須是一組可選項(至少2個),用於多選1。
此外,你可以不點擊任何的復選框,但是你必須點擊來選擇一個單選框,且你無法通過再次點擊同一個單選框來讓它處於未選中狀態,你只有通過選擇一組單選框中的其他兄弟選項來重置之前的狀態。
下拉菜單(Dropdown menus)
對於少量的選項,單選框和復選框已經可以滿足要求,但是如果選項很多時,從界面布局以及可擴展性的角度而言,選擇框是受到空間限制的。 而且對於大量的選項,我們還需要提供選項過濾功能以便快速定位選項,因此在這種情況下,我們需要使用新的表單界面組件: <select> 下拉列表框。 該控件通過滾動條和接受鍵盤輸入事件的界面設計無限擴展了選項可用空間。
下拉列表框同時支持單項或多項選擇,下面是月份選擇的下拉列表框控件:
<select> <option>January</option> <option>February</option> <option>March</option> <option>April</option> <option>May</option> <option>June</option> <option>July</option> <option>August</option> <option>September</option> <option>October</option> <option>November</option> <option>December</option> </select>
你可以試着輸入字母S,將很快定位到September選項,類似的,如果連續輸入May字符串,將直接定位到May選項。這大大加快了選項檢索過程。
上面的列表你只能選擇一個選項,要想選擇多個選項,可以通過設置 multiple 屬性:
<label>瀏覽器兼容性:</label> <select multiple> <option>Google Chrome</option> <option>Internet Explorer</option> <option>Mozilla Firefox</option> <option>Opera</option> <option>Safari</option> </select>
按住Ctrl(或⌘)鍵,然后點擊多個選項。重復點擊即取消之前的選項。
我們還可以使用<optgroup>給下拉列表框中的選項進行分組,這樣就能形成類似樹形的分級選擇控件。
下面給出一個完整包含上述各個元素的表單實例:
<form action="#" method="post"> <h1>Sign Up</h1> <fieldset> <legend><span class="number">1</span> Your basic info</legend> <label for="name">Name:</label> <input type="text" id="name" name="user_name"> <label for="mail">Email:</label> <input type="email" id="mail" name="user_email"> <label for="password">Password:</label> <input type="password" id="password" name="user_password"> <label>Age:</label> <input type="radio" id="under_13" value="under_13" name="user_age"> <label for="under_13" class="light">Under 13</label> <input type="radio" id="over_13" value="over_13" name="user_age"> <label for="over_13" class="light">Over 13</label> </fieldset> <fieldset> <legend><span class="number">2</span> Your profile</legend> <label for="bio">Biography:</label> <input id="bio" name="user_bio"></input> <label for="job">Job role:</label> <select id="job" name="user_job"> <optgroup label="Web"> <option value="frontend_developer">Front-End Developer</option> <option value="php_developer">PHP Developer</option> <option value="python_developer">Python Developer</option> <option value="rails_developer">Rails Developer</option> <option value="web_designer">Web Designer</option> <option value="wordpress developer">Wordpress Developer</option> </optgroup> <optgroup label="Mobile"> <option value="android_developer">Android Developer</option> <option value="ios_developer">iOS Developer</option> <option value="mobile_designer">Mobile Designer</option> </optgroup> <optgroup label="Business"> <option value="business_owner">Business Owner</option> <option value="freelancer">Freelancer</option> </optgroup> </select> <label>Interests:</label> <br> <input type="checkbox" id="development" value="interest_development" name="user_interest"> <label for="development">Development</label> <br> <input type="checkbox" id="design" value="interest_design" name="user_interest"> <label for="design">Design</label> <br> <input type="checkbox" id="business" value="business" name="user_interest"> <label for="business">Business</label> </fieldset> <button type="submit">Sign Up</button> </form>
*, *:before, *:after { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } :root { background-color: #2e4049; color: white; } form { width: 40%; max-width: 350px; margin: 0 auto 30px; } fieldset { background: #202d33; border-radius: 4px; border: none; border-top: 2px solid tomato; margin-bottom: 30px; box-shadow: 0 5px 30px rgba(0, 0, 0, .3); padding: 10px 15px; } legend { font-weight: bold; margin-bottom: 10px; padding-right: 10px; } .number { background: tomato; margin-right: 10px; padding: 10px 4px 4px; } h1 { margin: 60px 0; text-align: center; font-size: 3em; color: tomato; text-shadow: 0 1px 0 #ea553a, 0 3px 0 #b72b12, 0 7px 0 #420900, 0 5px 10px #0b3f3b, 0 5px 11px #ff546a, 0 0 20px tomato; } input[type="text"], input[type="password"], input[type="date"], input[type="datetime"], input[type="email"], input[type="number"], input[type="search"], input[type="tel"], input[type="time"], input[type="url"], textarea, select { background: rgba(255, 255, 255, 0.1); border: none; font-size: 16px; height: auto; margin: 0; outline: 0; padding: 10px; width: 100%; background-color: #e8eeef; color: #2e4049; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.03) inset; margin-bottom: 20px; } input[type="checkbox"] { margin: 0 4px 8px 0; } input[type="radio"] { margin: 0 2px 0 15px; } label { display: inline-block; margin-bottom: 10px; } button { display: block; width: 30%; margin: 50px auto 0; padding: 10px 20px; background-color: tomato; border: none; border-radius: 5px; font-weight: bold; text-shadow: 0 1px 0 rgba(0, 0, 0, .5); box-shadow: 0 2px 0 #ea553a, 0 4px 0 #b72b12, 0 6px 0 #420900, 0 6px 10px #0b3f3b, 0 6px 11px #ff546a, 0 0 20px tomato; } button:hover { text-shadow: 0 3px 2px rgba(0, 0, 0, .5); } button:active { box-shadow: 0 0px 0 #ea553a, 0 1px 0 #b72b12, 0 2px 0 #420900, 0 2px 10px #0b3f3b, 0 2px 11px #ff546a, 0 0 20px tomato; outline: 0; } button:focus { outline: 0; } @media (max-width: 840px) { form { width: 70%; } } @media (max-width: 490px) { form { width: 100%; } button { width: 50%; } }
為了布局的美觀,使用了CSS樣式,也就是接下來我們要講解的課程內容(http://techbrood.com/h5b2a?p=css-basics)。
