使用 :read-only 伪类可以精准选中没有 readonly 属性的表单元素,从而为只读和可编辑状态分别设置样式。通过组合选择器 :not(:read-only) 或 :read-write,你可以直接控制输入框的视觉表现,无需依赖 javascript 监听事件。

:read-only 与 :read-write 的选择逻辑是什么
这两个伪类的核心区别在于对 readonly 属性的判定。:read-only 匹配所有未启用编辑功能的元素,包括默认状态的文本框、带有 readonly 属性的元素以及 <fieldset></fieldset> 等。而 :read-write 则匹配允许用户输入的元素,即那些既没有 readonly 也没有 disabled 属性的元素。在实际开发中,通常利用 :read-write 来设置可编辑时的焦点效果,用 :read-only 来设置灰显或禁用交互的样式。

.input-readonly {
background-color: #f0f0f0;
color: #666;
border: 1px solid #ccc;
}
.input-read-write {
background-color: #fff;
color: #333;
border: 1px solid #007bff;
}
/* 应用样式 */
input:read-only, textarea:read-only, select:read-only {
@extend .input-readonly;
}
input:read-write, textarea:read-write, select:read-write {
@extend .input-read-write;
}上述代码展示了如何定义两组基础样式并应用到不同的伪类上。当输入框拥有 readonly 属性时,它将继承灰色背景;反之,如果移除该属性,输入框将变为白色背景并显示蓝色边框。这种写法比传统的 [readonly] 属性选择器更具语义化,且能自动处理某些元素的默认只读状态。
立即学习“前端免费学习笔记(深入)”;
如何处理 disabled 状态与 :read-only 的冲突
:read-only 并不包含 disabled 状态的元素。这意味着一个被禁用的输入框不会匹配 :read-only,而是需要单独处理。在 CSS 中,disabled 元素通常具有更高的特异性或独立的样式需求(如完全不可点击、更淡的颜色)。因此,在设计样式表时,必须明确区分这两种状态。如果希望禁用状态也呈现只读外观,需要同时使用 :read-only 和 :disabled 选择器,或者使用 :not(:read-write) 来捕获所有非编辑状态,但需注意 :not(:read-write) 也会匹配 disabled 元素。

/* 方案一:分别处理 */
input:read-only {
/* 只读样式 */
}
input:disabled {
/* 禁用样式 */
}
/* 方案二:统一非编辑状态 */
input:not(:read-write) {
/* 包含 readonly 和 disabled 的通用样式 */
pointer-events: none;
opacity: 0.6;
}在第二个示例中,我们对比了两种处理策略。第一种策略提供了更精细的控制,允许禁用状态有独特的视觉反馈。第二种策略则简化了代码,将所有无法编辑的状态统一处理。需要注意的是,:not(:read-write) 是一个强大的工具,但它可能会意外地选中一些你原本希望保持可交互的特殊元素,因此在实际项目中应根据具体需求选择合适的方案。此外,pointer-events: none 在非编辑状态下能有效阻止鼠标事件,提升用户体验。
如何在动态切换 readonly 属性时保持样式同步
当通过 JavaScript 动态添加或移除 readonly 属性时,:read-only 伪类会自动响应并更新样式,无需手动触发重绘或重新计算样式。这是因为伪类是基于元素的当前状态进行匹配的,而不是基于特定的类名。开发者只需确保在切换属性时正确使用了 setAttribute('readonly', '') 或 removeAttribute('readonly'),CSS 就会立即生效。这种机制使得动态表单验证和状态管理变得更加简单和可靠。


















