为何未禁用的复选框会被CSS :read-only伪元素匹配?
为什么未禁用的复选框会被
:read-only伪元素选中? 这个问题的核心在于对CSS :read-write 和 :read-only 伪类的匹配规则理解,尤其是表单控件类型的特殊性——复选框这类控件并不属于:read-write的匹配范围,因此会被:read-only选中。
先明确两个伪类的核心规则
根据CSS规范的定义:
:read-write匹配用户可以编辑文本内容的元素,包含两类:- 设置了
contenteditable="true"的元素; <input>/<textarea>这类表单元素,但必须同时满足:未设置readonly/disabled,且属于可编辑文本的控件类型(比如text、email、password等)。
- 设置了
:read-only则是匹配所有不满足:read-write条件的元素(除了select等少数特殊控件例外)。
复选框为什么不匹配:read-write?
你提到复选框的值可以被用户切换,但这里的“切换状态”和:read-write定义的“编辑文本内容”不是一个概念。复选框、单选按钮这类控件,它们的交互是选择/切换状态,而不是输入或修改文本值,因此即使没有设置disabled,也不会被:read-write匹配。
反过来,既然复选框不满足:read-write的条件,自然就会被:read-only选中——这就是你看到的现象:未禁用的复选框和禁用的文本框都触发了input:read-only + label的红色背景。
关于旧Chrome版本的异常行为
旧版本Chrome(比如89.x)的行为不符合规范,是因为当时浏览器对这些伪类的实现还没有完全对齐CSS Selectors Level 4的标准。后续Chromium内核更新后(包括你测试的Brave基于的92.x版本),和Firefox一起修正了这个行为,现在的表现才是符合规范的。
如何正确选中可交互的复选框?
如果要选中未禁用的复选框,应该直接使用:not(:disabled)选择器,而不是依赖:read-write,比如:
input[type="checkbox"]:not(:disabled) + label { background-color: green; }
你的测试代码验证
我们可以再对应你的代码看规范下的行为:
input:read-write + label { background-color: green; } input:read-only + label { background-color: red; }
<!-- 未禁用的复选框:不匹配:read-write → 被:read-only选中 → 红色背景 --> <input type="checkbox" id="checkbox" /> <label for="checkbox">the checkbox</label> <br /> <br /> <!-- 禁用的文本框:匹配:read-only → 红色背景 --> <input type="text" disabled id="text"/> <label for="text">the text</label> <br /> <br /> <!-- 未禁用的文本框:匹配:read-write → 绿色背景 --> <input type="text" id="text-active"/> <label for="text-active">another text</label>
现在的浏览器行为完全符合规范:只有未禁用的文本输入框触发了绿色背景,其他两个都触发红色背景。
内容的提问来源于stack exchange,提问作者Nicolas
相关产品推荐
相关产品推荐

