只有(文本类type)和能真正匹配:read-only;、、、等均无效,浏览器仅识别dom中真实存在的readonly布尔属性。

哪些元素能真正匹配 :read-only
只有两类原生表单控件会被识别:<input>(但仅限 type="text"、type="email"、type="number" 等文本类)和 <textarea></textarea>。其他都无效:<select></select> 行为不一致,<input type="checkbox"> 和 <input type="hidden"> 完全不支持,<div readonly> 或自定义组件加 <code>readonly 属性也白搭——浏览器直接忽略。
:read-only 样式不生效的常见原因
根本不是选择器写错,而是元素压根没进入只读状态。浏览器只认 DOM 中真实存在的 readonly 布尔属性:
- HTML 里写
<input readonly>✅ - JS 里调用
el.setAttribute('readonly', '')✅ - JS 里只设
el.readOnly = true❌(DOM 属性未出现,伪类不触发) - 用了
disabled或contenteditable="false"误以为等价 ❌
打开 DevTools 的 Elements 面板,确认目标标签上真有 readonly 字样,否则别调试 CSS。
怎么写才稳妥:兼容性与样式组合
纯靠 :read-only 会丢掉 IE 全系、旧 Edge(≤17)和部分老 Safari 用户。必须降级:
- 优先用属性选择器兜底:
input[readonly], textarea[readonly] - 再叠加伪类增强:
input:read-only, textarea:read-only, input:-moz-read-only, textarea:-moz-read-only - 别写
input[readonly="true"]——readonly是布尔属性,值为空也匹配 - 加
cursor: not-allowed比单改背景色更能提示不可编辑 - 避免用
opacity或filter: grayscale(),它们会降低可读性或干扰渲染
推荐组合:background-color: #f5f5f5 + color: #666 + border-color: #ddd + cursor: not-allowed。
:read-only 和 :disabled 别混着用
两者语义和行为完全不同,共存时容易出视觉陷阱:
-
:read-only元素仍可聚焦、双击选中文本、右键粘贴、提交值 -
:disabled元素禁焦点、禁事件、不提交、灰化外观 - 若一个
<input readonly disabled>,:disabled样式一定覆盖:read-only(同权重下后声明者胜出) - 别为了“看起来更禁用”同时加两个属性——它会让表单逻辑混乱:值该不该提交?用户该不该复制?
真正容易被忽略的是::read-only 只是视觉钩子,不拦截任何交互。要禁粘贴得监听 paste 事件,要禁聚焦得配 tabindex="-1" 和 user-select: none。











