pattern属性仅在提交或checkValidity()时校验,需配合required使用;正则须为裸字符串(如"[0-9]{6}"),不加^$;type="number"无视pattern;title是唯一可自定义提示方式;复杂校验必须用JavaScript实现。

pattern 属性不是实时拦截器,它只在表单提交或调用 checkValidity() 时才校验;不加 required 很可能“形同虚设”,空值直接跳过验证。
pattern 的正则必须写成裸字符串,不能带 / 或 ^$
浏览器内部会自动把 pattern 值当作 ^...$ 全匹配处理,你写的只是中间部分。写成 /^[0-9]{6}$/ 或 ^[0-9]{6}$ 都是错的——前者把斜杠当字面字符,后者虽不报错但冗余且易因转义出问题。
- ✅ 正确:
pattern="[0-9]{6}"(6位纯数字) - ✅ 正确:
pattern="1[3-9]\d{9}"(11位手机号,注意\d在 HTML 中可直接用,但旧版 Firefox 可能不支持,稳妥起见用[0-9]) - ❌ 错误:
pattern="/[0-9]{6}/"、pattern="^[0-9]{6}$"、pattern="[0-9]{6}?"(?在 pattern 中不被识别为量词修饰符) - ⚠️ 字符类里
-必须放开头或结尾,否则解析失败:用[a-z_.+-],别用[a-z%+-]
type="number" 完全无视 pattern,别踩这个坑
pattern 只对 text、tel、email、url、password、search 生效;type="number" 会先把输入转成数值,再丢掉 pattern —— 用户输 00123 直接变成 123,pattern="[0-9]{5}" 永远不匹配。
- 要限制 6 位数字验证码?用
type="text" inputmode="numeric",既唤起数字键盘,又保留原始字符串 - 要校验手机号?优先选
type="tel",iOS 不会自动补零或删前导 1,比number可靠 -
type="email"自带基础检查(必须含 @、不能以 @ 开头),pattern是增强,不是替代
title 是唯一可控提示出口,不写就等于没提示
验证失败时,浏览器默认提示是“请与所要求的格式匹配”这类笼统文案,中文用户根本看不出哪错了。而 title 是唯一能自定义的地方,且会在 hover 和错误气泡中显示。
- ✅ 写具体:
title="请输入11位手机号,不要加空格或括号" - ✅ 匹配失败时,
input.validationMessage返回的就是title内容(若设置了),否则是浏览器默认文案 - ⚠️ iOS Safari 对
title支持弱,部分机型不弹提示,需 JS 补充反馈 - ⚠️ 用户修改后再次提交仍报错?因为
validity状态未刷新,得手动调用reportValidity()或在input事件里清空自定义错误
复杂逻辑必须交给 JavaScript,pattern 只适合静态规则
pattern 天然不支持跨字段校验(如两次密码一致)、上下文判断(如“如果选了A,则B必须填”)、动态长度约束(如“用户名长度 = 邮箱本地部分长度 + 2”),也做不到实时标红或滚动定位。
- 需要边输边提示?监听
input事件,调用input.checkValidity()判断,配合setCustomValidity("")清除旧状态 - 要兼容老浏览器(如 Android 4.4 WebView)或强中文校验?放弃
[\u4e00-\u9fa5],改用长度 + ASCII 组合兜底 - 永远别信前端验证:用户可禁用 JS、绕过表单、直接发请求,后端必须用独立正则重校一遍
最常被忽略的是:pattern 不 trim(),不忽略粘贴进来的换行和空格,也不高亮错误字段——它只负责在提交那一刻说“不行”,至于怎么告诉用户、怎么修正、怎么兜底,全得你来补。

















