表单
表单是用户与网站交互的入口——登录、注册、搜索、提交订单、发评论都靠它。这一章讲清表单容器(form)、各类输入控件、HTML5 新增的类型和内置校验。
1. 表单容器 form
所有表单控件都要包在 form 里。form 的两个核心属性:
- action:提交到哪个 URL(后端接口地址)。如果不写,默认提交到当前页。
- method:提交方式,
get或post。敏感数据(密码、订单)用 post(不显示在地址栏);查询关键词等用 get(可分享链接)。
<form action="/login" method="post">
<label>用户名:
<input type="text" name="user" required>
</label>
<label>密码:
<input type="password" name="pwd" required>
</label>
<label>性别:
<select name="gender">
<option value="m">男</option>
<option value="f">女</option>
</select>
</label>
<button type="submit">提交</button>
</form>重点:每个 input 必须有 name 属性——后端接收数据是按 name=value 形式,漏写 name 这个字段就传不过去。这是新手最容易踩的坑。
2. label — 表单字段的文字
label 是输入框旁边的文字标签。它的核心价值:点击文字也能聚焦对应的输入框——这对视障用户和触屏用户极其友好。
两种写法:
- 包裹式(推荐):
<label>用户名:<input></label>,文字和输入框放一起。 - for 关联式:
<label for="x">配<input id="x">,文字和输入框分开写,通过 id 关联。
表单上一定要用 label——不要直接写裸文字,会丢失无障碍和易用性。
3. input 的各种 type
input 通过 type 属性切换不同输入框,是表单的核心。HTML5 引入了大量新类型,移动端还会自动切换键盘:
<!-- 文本框(默认) -->
<input type="text" name="nickname" placeholder="昵称">
<!-- 密码框:输入显示为圆点 -->
<input type="password" name="pwd">
<!-- 邮箱:移动端键盘出 @ 符号 -->
<input type="email" name="mail">
<!-- 数字:带上下箭头 -->
<input type="number" name="age" min="0" max="150">
<!-- 电话:移动端拨号键盘 -->
<input type="tel" name="phone">
<!-- URL:必须以 http:// 开头 -->
<input type="url" name="website">
<!-- 日期选择器 -->
<input type="date" name="birthday">
<!-- 滑块 -->
<input type="range" name="volume" min="0" max="100">
<!-- 颜色选择器 -->
<input type="color" name="bg">
<!-- 文件上传 -->
<input type="file" name="avatar">移动端的体验差异非常明显:type="email" 键盘会出 @,type="tel" 出拨号键盘,type="number" 出数字键盘。所以选对 type 不只是语义,还直接影响用户体验。
4. 单选 radio 和 复选 checkbox
单选按钮用 type="radio",复选框用 type="checkbox"。关键是单选的多个选项name 必须相同才能互斥:
<!-- 单选:name 必须相同,才能互斥 -->
<label>
<input type="radio" name="gender" value="m"> 男
</label>
<label>
<input type="radio" name="gender" value="f"> 女
</label>
<!-- 复选:name 用数组形式 -->
<label>
<input type="checkbox" name="hobby" value="read"> 阅读
</label>
<label>
<input type="checkbox" name="hobby" value="code"> 写代码
</label>
<!-- 默认选中:checked 或 checked="checked" -->
<input type="radio" name="g" value="m" checked>
<input type="checkbox" checked>注意复选框的 name 用数组形式(如 hobby[] 或同名的多个),后端才能收到所有勾选的值。
5. textarea 多行输入
单行用 input,多行大段文字用 textarea。它没有 value 属性,内容写在开始结束标签之间:
<!-- 单行输入:input -->
<input type="text" name="title" maxlength="50">
<!-- 多行输入:textarea -->
<textarea name="content" rows="5" cols="40">
这里可以输入大段文字。
rows 控制行数(高度),
cols 控制列数(宽度)。
</textarea>
<!-- 现代 CSS 项目里 rows/cols 通常用 CSS 的
height/width 替代,但保留 rows 利于可访问性 -->6. select 下拉选择
下拉菜单用 select,每个选项用 option:
<!-- 基本:select 包 option -->
<select name="city">
<option value="bj">北京</option>
<option value="sh">上海</option>
<option value="gz">广州</option>
</select>
<!-- 默认选中某项:selected -->
<select name="city">
<option value="bj">北京</option>
<option value="sh" selected>上海</option>
</select>
<!-- 分组:optgroup -->
<select name="area">
<optgroup label="华北">
<option value="bj">北京</option>
<option value="tj">天津</option>
</optgroup>
<optgroup label="华东">
<option value="sh">上海</option>
<option value="hz">杭州</option>
</optgroup>
</select>option的value是提交到后端的值,标签内的文字是用户看到的。selected属性设置默认选中。- 加
multiple属性可以多选(按住 Ctrl/Cmd),但用户体验不好,少用。 - 用
optgroup给选项分组,配label写组名。
7. button 按钮
按钮用 button。三种 type:
type="submit"(默认):点击触发表单提交。type="button":普通按钮,不会提交,需要 JS 配合。type="reset":重置表单到初始值(很少用,容易误操作)。
注意:在 form 里的 button 如果不写 type,默认是 submit——容易误触发提交,所以不想要提交时一定要写 type="button"。
8. HTML5 内置校验
HTML5 提供了一批"校验属性",不用写 JS 就能挡住常见错误,提交时浏览器自动拦截:
<!-- required:必填,不填不能提交 -->
<input type="text" name="user" required>
<!-- maxlength:最大字符数 -->
<input type="text" maxlength="20">
<!-- min / max / step:数值范围 -->
<input type="number" min="18" max="99" step="1">
<!-- pattern:正则校验 -->
<input type="text" pattern="[0-9]{6}" title="请输入 6 位数字">
<!-- type="email" 自带邮箱格式校验 -->
<input type="email" required>
<!-- novalidate:关闭浏览器校验 -->
<form novalidate>...</form>这些校验只针对"格式层面",真正的业务校验(账号是否被注册、库存够不够)必须由后端做。前端校验是为体验,后端校验是为安全——前端校验可以被用户改 JS 绕过,绝对不能替代后端。
9. 表单提交的本质
表单提交时,浏览器把所有"成功控件"(有 name 且非 disabled)按 name=value 拼起来:
method="get":拼到 URL 问号后(如/search?q=apple),可分享、可收藏。不要用于敏感数据。method="post":放在请求 body 里,不在地址栏显示。适合密码、上传文件。
现代前后端分离项目里,通常不再用原生表单提交,而是用 JS 监听 submit 事件、用 fetch/ajax 异步发送——但表单的语义结构依然重要,它对无障碍、键盘操作、密码管理器自动填充都有用。
10. 实战示例:注册表单
把所有概念组合起来,做一个真实的注册表单:
<form action="/login" method="post">
<label>用户名:
<input type="text" name="user" required>
</label>
<label>密码:
<input type="password" name="pwd" required>
</label>
<label>性别:
<select name="gender">
<option value="m">男</option>
<option value="f">女</option>
</select>
</label>
<button type="submit">提交</button>
</form>每个字段都有 label、合理的 type、必要的校验属性。这就是一个高质量 HTML 表单的样子。
小结
这一章你掌握了表单的完整生态:容器 form、各类 input、textarea、select、单选复选、button,以及 HTML5 内置校验。记住三个原则:每个字段配 label、每个 input 写 name、前端校验只是体验,后端校验才是安全。下一篇我们看现代 HTML 的精髓——语义化标签。
← 上一篇 列表与表格
下一篇 语义化标签 →