:required伪类本身不显示红星,必须配合::after等伪元素在label上插入content:"*";因input是替换元素,直接对其使用::after不可靠,推荐label:has(> :required)::after或降级为label.required::after。

如何用 :required 伪类给必填项加红星
直接加 :required 不会自动显示红星,它只是个状态选择器,得配合 ::after 或边框/背景等样式手动渲染星号。常见写法是加在 label 后或输入框右侧,但位置和可访问性要小心。
推荐做法:在关联 label 后插入星号(最稳妥)
把星号放在 label 文本末尾,语义清晰、屏幕阅读器能自然读出「用户名 *」,且不干扰表单控件本身。前提是 input 有 required 属性,且 label 正确绑定(用 for 或包裹)。
-
label:has(input:required)是较新方案,但 Safari 15.4+ 才支持,兼容性有限 - 更通用的做法是给带
required的label加 class,或直接写label[for="name"]:has(input[required])::after - 实际推荐手写结构:
<label for="email">邮箱地址</label><input type="email" id="email" required>
,然后用:label[for] input:required { /* 样式可选 */ }<br>label[for] input:required + label::after { content: " *"; color: #e32; }——但注意这个依赖相邻兄弟关系,结构易断 - 最稳的是:
label.required::after { content: " *"; color: #e32; font-size: 0.9em; },并在 HTML 中显式加class="required"
避免在 input 上用 ::after 直接加星号
input 是替换元素,::after 在大多数浏览器里默认不生效(除非设成 display: inline-block 并给宽高,但会破坏原生布局)。
- 强行启用需:
input:required { position: relative; }<br>input:required::after { content: "*"; position: absolute; right: -12px; top: 50%; transform: translateY(-50%); color: #e32; } - 问题很多:星号可能被截断、焦点框遮挡、移动端缩放错位、暗色模式下颜色不协调
- 若用
background-image模拟星号,又难对齐、难适配高 DPI
为什么不用 JavaScript 动态加星号
纯 CSS 方案更轻量、无 FOUC、服务端渲染友好。但要注意::required 只匹配含 required 属性的元素,不反映运行时校验状态(比如 JS 动态增删属性后,样式不会重算,除非触发重排)。
- 动态表单中,如果 JS 移除了
required属性,CSS 星号会立即消失;但若只调用setCustomValidity(),:required依然匹配 - 想响应“当前是否必填”的逻辑,得结合
data-required="true"和对应 CSS,而不是依赖原生伪类 - 无障碍方面,仅靠视觉星号不够,必须确保
aria-required="true"或错误消息明确提示
真正容易被忽略的是:星号不是装饰,它是表单必要性的视觉契约。一旦加了,就要保证所有必填字段都一致呈现,且在禁用 JS、高对比度模式、字体放大 200% 时仍清晰可辨。别为了“一行 CSS”牺牲可访问性底线。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











