:required伪类本身不生成内容或样式,仅用于匹配带required属性的控件;星号需配合::after等伪元素插入,且必须加在label上(因input等替换元素不支持伪元素),推荐label:has(> :required)::after或降级为label.required::after。
:required 本身不会显示星号:required 只是一个匹配状态的伪类,它不生成内容,也不改变视觉样式——它只是帮你“选中”那些带 required 属性的表单控件。想让星号出现,必须配合 ::after 或 ::before 伪元素插入内容。
::after 在 label 后加星号最稳妥直接给 input:required::after 加星号会失败:表单控件(如 input、select)是替换元素,大多数浏览器不支持在它们上面使用 ::before/::after(尤其是 input[type="text"] 等)。正确做法是把星号加到关联的 label 上:
label:has(> :required) ::after { content: " *"; color: #e74c3c; font-weight: bold;}
但注意::has() 在旧版 Safari 和部分安卓 WebView 中不支持。兼容性要求高时,改用显式 class 或 JS 注入更可靠。
label 正确 for 关联或包裹 input,否则 :has() 不生效label:required::after —— label 元素本身没有 required 属性,这个选择器永远不匹配" *"),避免紧贴文字影响可读性:has() 的降级方案如果要支持 Safari 15.4 之前版本或 IE,推荐在 HTML 中显式标记必填项,例如:
立即学习“前端免费学习笔记(深入)”;
<label>姓名<span class="required-star" aria-hidden="true"> *</span></label><input type="text" required>
再配 CSS:
.required-star { color: #e74c3c; font-weight: bold;}
aria-hidden="true" 防止屏幕阅读器重复播报“星号”,语义仍由 required 属性保障input + label::before —— 表单控件和 label 的 DOM 顺序常不固定,相邻兄弟选择器容易失效DOMSubtreeModified 或用 MutationObserver,防止后续动态插入的 required 字段漏处理纯红色星号(#e74c3c)对色觉障碍用户可能不可见。真正合规的做法是:
aria-label 强化语义,例如:<label aria-label="姓名(必填)">姓名</label>
color + border-bottom 或 text-decoration 双重提示,比单靠颜色更鲁棒background-image 替代伪元素——它无法被高对比度模式识别,且缩放时易模糊星号本身不是问题,问题在于把它当成唯一提示手段。真正的必填逻辑始终靠 required 属性驱动,样式只是辅助。