required属性仅在提交时强制校验,不自动提供视觉反馈;需手动添加失焦验证、自定义提示文案(setcustomvalidity)、无障碍支持(aria-required)及兼容处理(如移动端降级js校验)。

加 required 属性本身不会自动显示提示文字或红框,它只在提交时“硬拦”,视觉反馈、失焦校验、文案定制全得你手动补。
为什么写了 required 却没弹窗也没高亮
不是属性写错了,而是校验根本没触发。常见断点有:
-
form标签缺失或被 JS 移除——required必须依附语义化表单 - 用了
<button type="button"></button>或没写type(默认是button),浏览器不启动验证流程 - 在
submit事件里写了e.preventDefault(),却没紧接着调form.checkValidity()或form.reportValidity() -
select的空选项写成<option value="">请选择</option>但没加disabled,用户不动它就一直卡在校验失败状态 - 旧版 iOS Safari(≤15.4)对
type="file"或type="select"的required支持不稳定,checkValidity()可能返回true却实际未填
让红边/星号/提示文字“等用户动过再出现”
别用 input:required:invalid 一加载就生效,否则页面刚打开所有必填框全变红。正确做法是延迟反馈:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 给
input加placeholder,然后用input:invalid:not(:placeholder-shown)控制样式 -
textarea和select不支持:placeholder-shown,得单独写规则,比如textarea:invalid:not(:focus), select:invalid option[value=""]:not(:checked) - 想让星号同步可读屏:除了
label::after { content: " *"; },还得加aria-required="true" - 失焦即提示?监听
blur后调el.reportValidity(),它会弹气泡且返回布尔值,比setCustomValidity()更轻量
自定义提示文案的唯一可靠路径
浏览器默认提示(如“请填写此字段”)无法通过 HTML 或 CSS 修改,oninvalid 事件也不推荐——它只在首次失败时触发,且不能阻止默认弹窗。真正可控的方式只有:
- 输入为空时调
el.setCustomValidity("此项不能为空") - 非空时**必须立刻**调
el.setCustomValidity("")清空,否则后续所有校验都失效 - 别在
input事件里反复设setCustomValidity(),容易让浏览器内部validity状态混乱 -
title属性可作为轻量 fallback:<input required title="此项为必填项">,部分浏览器在校验失败时会优先展示它
移动端和框架里最容易忽略的点
原生 required 在真实场景中常被环境绕过:
- React/Vue 等框架中,受控组件若初始化
value不是""(比如初始为null或undefined),首次渲染就可能触发:invalid,导致误标 - 微信内置 WebView(尤其旧版本)直接忽略
required,reportValidity()也不弹,必须降级为 JS 手动遍历querySelectorAll('[required]')+trim().length === 0 -
input type="text"对空格不敏感:“ ”算已填;但后端永远要trim()再判空,前端拦不住 curl 或禁用 JS 的请求 -
type="date"的required只检查value === "",2024-02-30 这种非法日期照样过——格式校验必须另加 JS 或后端兜底
最常被跳过的其实是交互前提:浏览器不会因为写了 required 就主动高亮,它只响应用户行为后的状态。想“一进页面就标出所有空项”,必须用 JS 主动调 form.reportValidity(),纯 CSS 没法绕过这个限制。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










