09表单进阶

上一课你认识了「裸 <input>」和它的七个兄弟。这一课走进 HTML5 给表单开的新挂:浏览器能识别十多种语义类型、自动校验格式、 记住上次输入,写一个完整注册页从此少写一半 JS。

约 18 分钟 7 个动手实验 HTML5 新增

一、HTML5 表单的革命:浏览器替我们做一半

上一课讲的 text / password / radio / checkbox / submit / reset / button 是 HTML 老四件。再新一点的设计稿里你一定会遇到这样的代码: <input type="email">、<input type="date">、 <input type="range">——这些全是 HTML5 才加进来的新类型。

它们做了一件了不起的事:把以前要写几百行 JS 才能搞定的事交给浏览器原生处理。 具体三件:

  • 自动校验:邮箱、网址、数字范围——格式不对浏览器直接红框拦下,连后端都不用去。
  • 专属键盘:手机端点 email 出 @ 键盘,点 number 出纯数字键盘,体验天差地别。
  • 自带 UI:日历下拉、颜色拾色器、滑动条——零依赖、零资源加载。
这一课以「HTML5 新成员」为主线,重点是上一课没覆盖的 13 个新 type、全新属性、datalist 智能提示、progress / meter 度量家族。 上一课讲过的基础不会再重复。

二、input 新增类型(按使用频率分组展示)

13 个新 type,按「能干什么」分三组记忆:键盘 / 校验组(email、url、tel、search)、 数值 / 选择组(number、range、color)、 日期 / 文件组(date、time、month、week、datetime-local、file)。

input 新类型速查:触发键盘 / 校验规则 / 适用场景
type触发键盘(移动端)自带校验典型场景
email带 @ 的英文键盘必须含 @ 与域名注册邮箱、联系邮箱
url带 / 与 .com 键必须是合法 URL个人主页、来源网址
tel纯数字拨号盘无(电话格式各国不同)联系电话
search普通键盘,部分浏览器带「清除叉」无站内搜索框
number纯数字键盘 + 上下调整按钮必须为数字,配 min/max/step年龄、数量、价格
range—必须为数字,配 min/max/step音量、亮度、价格区间
color—必须为 #RRGGBB 格式主题色、皮肤色
date—合法日期生日、预约日
time / month / week—合法时间 / 月 / 周营业时间、月份统计
datetime-local—本地时区日期 + 时间会议预约、活动时间
file系统文件选择器配 accept 限定类型头像、附件、导入
把它们逐个改成 number / range / color / date 看渲染差异:phone 框里点上下箭头一次 +1;color 框点开弹出系统拾色器
type="number" 的 step 默认是 1—— 写 min="0" max="100" step="5" 表示只允许 0、5、10…100 这种倍数, 不在倍数上的值(如 7)会被认为无效。密码学场景尤其要注意, 别让用户以为能填任何数字。

三、input 新增属性(按作用分组)

类型告诉你「这是什么控件」,属性告诉你「它该多严、怎么交互」。HTML5 把零散的属性按校验 / 交互 / 输出三类一次给齐。

input 新属性速查:校验 / 交互 / 输出三大类
分类属性作用
校验类required不能为空(提交时拦截)
pattern正则匹配(如手机号 1[3-9]\d{9})
min / max数字 / 日期范围
step数字步长、range 滑杆步长
minlength / maxlength字符长度区间
type 自带email / url / number 等已自带格式校验
交互类placeholder灰色占位提示
autofocus页面加载后自动聚焦
autocomplete浏览器是否记忆输入:on / off
list指向一个 <datalist> 的 id,绑定候选词
form控件不在 form 内时,用它指明归属哪个表单
输出类name提交时的键名(不写 = 不提交)
value当前值 / 初始默认值
一个完整注册表单元件:依次给 input 加 required / pattern / minlength,看错误提示气泡(浏览器原生提示,纯 HTML 触发,零 JS)
autocomplete="off" 经常用在「不希望浏览器记住」的字段—— 比如一次性邀请码、测试题答案。但搜索框、姓名、地址这些常用信息 一定要留着 on,用户体验直线提升。 Chrome 还支持更细的 autocomplete="email" / "current-password",提示浏览器填哪类信息。

四、文本域与按钮族

<textarea> 是「可换行的输入框」,初始值写在标签中间, 没有 value 属性。按钮则有三态:submit 提交、reset 重置、 button 普通。

textarea 全属性与 button 三态
标签 / 属性作用备注
rows默认可见行数(高度)实际高度可被 CSS 覆盖
cols默认列数(宽度)现代项目一般用 CSS width 控制
maxlength最大字符数超出后无法继续输入
wrap提交时是否保留换行soft(默认,屏幕显示换行)/ hard(必须配合 cols 使用)
button type="submit"提交所在表单button 默认就是 submit,忘写 type 会闯祸
button type="reset"清空表单回到初始值慎用,会清空用户已填内容
button type="button"普通按钮JS 自定义行为时一定加这个
<button> 不写 type 默认就是 submit:把第二个按钮的 type="button" 摘掉,看它变成「提交」字样——这正是表单里的经典事故
<button> 与 <input type="submit"> 都能提交表单, 但 button 里可以放富文本(图标、多行文字),input 只能放纯文本属性。 现代项目首选 <button>,button 不写 type 时默认是 submit—— 「取消」键忘了写 type="button" 就直接把表单交了的现场,每年都有人重演。

五、选择类控件:select / optgroup / datalist

选择类控件三家:<select> 是纯下拉(用户只能选), <datalist> 是输入 + 下拉二合一(用户既可输入也可选), radio / checkbox 上一课已讲过。给 select 的选项分组用 <optgroup label="...">。

select / option / datalist 关键属性
标签关键属性作用
optionvalue提交给服务器的值(与显示文字分离)
optionselected默认选中(可多个,select 多选时生效)
optiondisabled该项不可选(变灰)
optgrouplabel给选项分组,渲染为不可选的标题
datalistid与 input 的 list="…" 对接
selectmultiple多选(按住 Ctrl / Cmd 点)
selectsize="n"显示 n 行而非下拉
可输入也可选的「城市」datalist:在输入框里打「上」,看 datalist 冒出候选;不选继续打完也能提交——二合一的体验
datalist 在 Safari 上的样式与桌面浏览器略有差异, 极少数移动端浏览器不渲染候选框只当普通输入框。 关键场景(如下单选地址)建议配合 JS 兜底方案,避免用户找不到选项。 另外 datalist 的 option 必须写 value, 只写文字不会成为候选项。

六、状态显示三件套:output / progress / meter

表单不只是「输入」,还要「输出」:实时的计算结果、进度提示、数值度量。 HTML5 给了一套零 JS 的展示组件。

  • <output>:展示计算结果。语义上是「这段文字是程序算出来的」, 真实场景需要 oninput 触发 JS 才能实时更新——本课只能静态演示写法。
  • <progress>:任务进度。必填 value 与 max, 不确定进度时省略 value,浏览器显示「忙碌中」动效。
  • <meter>:标量度量。除 min / max / value 外, 还有 low / high / optimum 三档警戒线——越界浏览器自动变黄或变红。
progress / meter 两种渲染差异与典型场景对比:把第二个 meter 的 value 改成 0.92,看它越过 high 自动变红警示
progress vs meter 怎么选—— 「任务完成了多少」用 progress(上传、加载、安装步骤); 「某个数值处于哪个区间」用 meter(电量、温度、磁盘占比、评分)。 meter 的 optimum 是「最佳值」位置,结合 low / high 三档配色让浏览器自动算色。

七、分组与可访问性:fieldset + legend

表单控件一多,眼睛就乱。<fieldset> 把一组相关控件圈成一个 分组框,<legend> 给框写标题—— 视觉上是边框标题,语义上是为读屏软件声明「这是一组相关控件」。

配合上一课的 <label>,就能搭出完整的无障碍表单: 读屏软件逐项念「分组标题 → 控件标签 → 控件输入 → 错误提示」, 键盘 Tab 键也会按分组逻辑跳转。

两个分组对照:左边裸控件无分组,右边 fieldset/legend 自动形成分组框——视觉有界、读屏有声
实际项目里 fieldset 常被设计师嫌「丑」——它的默认样式很朴素。 解法:写 CSS 重置 border / border-radius / padding,保留它的语义, 视觉外观交给设计稿。一个有 fieldset 的表单和一个没有的表单, 在屏幕阅读器里的体验差距是巨大的。

八、本章小结

  • HTML5 给表单开了挂:13 个新 type、10+ 新属性、自带校验 / 专属键盘 / 原生 UI。
  • 键盘 / 校验组(email、url、tel、search)改的是「输入体验」;数值 / 选择组(number、range、color)改的是「控件长相」。
  • 日期家族五兄弟:date / time / month / week / datetime-local,记牢 datetime-local 带时区。
  • 校验属性必记四件套:required / pattern / min-max / minlength,提交时浏览器自动拦。
  • <button> 默认 type="submit",普通按钮必须手写 type="button"。
  • <datalist> = 输入框 + 候选下拉二合一;<select> 是纯下拉。
  • progress 显任务进度,meter 显标量区间(含 low/high/optimum 警戒线);output 是计算输出(需少量 JS)。
  • fieldset + legend 是分组框兼无障碍神器,搭上 label 才算完整可访问表单。
动手任务:拼装一个完整「注册表单」——禁用 JS、纯 HTML5 校验。 要求:邮箱用 type=email required、手机号用 pattern 正则、 出生年月用 type=date、年龄区间用 type=range min max、 城市用 <input list> + <datalist>、 提交用 <button type="submit">、表单整体用 <fieldset><legend> 分两组(基本信息 / 偏好设置)。 提交时故意填错,看浏览器红框警告怎么出现——这是 HTML5 的免费门槛。