HTML原生校验需注意type与属性兼容性:pattern仅对文本类type生效,number类不支持pattern和maxlength;required在checkbox/radio中按组生效,file/date/time行为特殊;日期和邮箱校验仅为格式检查,服务端必须二次验证。

HTML 原生校验能解决 80% 的基础约束需求,但必须清楚哪些属性在哪些 type 下才生效,否则写了也白写。
type 和 pattern 不兼容时验证会静默失效
比如 type="number" 的输入框加了 pattern,浏览器直接忽略——因为 pattern 只对 text、tel、email、password 等文本类 type 生效。想校验数字格式又需要正则,得换用 type="text" 并配合 inputmode="numeric" 触发数字键盘,再用 pattern 控制内容。
- 错误写法:
<input type="number" pattern="\d{6}">→ pattern 不起作用 - 正确写法:
<input type="text" inputmode="numeric" pattern="\d{6}"> - 移动端用户仍能输字母,但提交时浏览器会弹出提示(title 属性可自定义提示文案)
required 对某些 type 无效或行为异常
required 在 type="checkbox" 和 type="radio" 上是按组生效的,单个 checkbox 加了 required 并不表示“必须勾选”,而是“该组至少一个被选中”。而 type="file" 的 required 表示“必须选中至少一个文件”,但若用户点了取消选择,值为空字符串而非 null,校验可能误判。
- 多选场景:一组
name="hobby"的 checkbox,只需其中一个带required即可触发组级校验 - 文件上传:建议搭配 JavaScript 监听
change事件,检查files.length > 0更可靠 -
type="date"或type="time"加required后,空值会被视为非法,但用户未点击选择器时字段仍是空字符串,校验有效
maxlength 在 number 类型上完全不生效
maxlength 是纯字符长度限制,而 type="number" 的值是数值类型,浏览器会自动忽略该属性。想限制位数(比如只允许输 5 位数字),只能靠 JavaScript 拦截:
立即学习“前端免费学习笔记(深入)”;
<input type="number" oninput="this.value = this.value.replace(/[^0-9]/g, '').slice(0, 5)">
- 不能只靠
max="99999",因为用户仍可输入100000再手动删减,max只控制增减按钮和提交校验 - 用
oninput过滤非数字并截断,比onblur更及时,避免用户看到超长输入后再跳转 - 注意:该写法会清空小数点和负号,如需支持,正则要调整为
/[^0-9.-]/g并加逻辑判断
日期和邮箱的“看似校验”实为陷阱
type="date" 看似能防非法日期,但它只校验格式(YYYY-MM-DD),不校验语义(比如 2023-02-30 会被自动转成 2023-03-02)。同理,type="email" 只检查是否含 @ 和 .,test@.com 也能通过。
- 服务端必须二次校验,前端不能信任任何 type 自带逻辑
- JS 中验证日期请用:
new Date(dateStr).toISOString().slice(0,10) === dateStr - 邮箱强校验建议后端用 SMTP 连通性检测,前端仅做基础格式提示
真正难处理的不是怎么写属性,而是当多个约束叠加(比如 required + pattern + maxlength)时,浏览器默认错误消息无法定制,且不同浏览器提示位置、样式、触发时机不一致——这时候就得用 setCustomValidity() 接管全部逻辑,但代价是放弃所有原生行为。



















