:read-only 伪类仅匹配真实含 readonly HTML 属性的 (非 hidden)和 ,不响应 disabled、contenteditable="false" 或仅 JS 设置的 readOnly;Safari ≤15.3 对 type="number" 有漏匹配 bug, 和 完全不支持。

:read-only 伪类只对真实写了 readonly 属性的 (非 type="hidden")和 生效,不响应 disabled、contenteditable="false" 或仅 JS 设置的 element.readOnly = true;Safari ≤15.3 对 type="number" 有漏匹配 bug, 和 完全不支持。
为什么 :read-only 样式没反应?先看 DOM 里有没有 readonly
浏览器只检查 HTML 属性是否存在,不关心 JS 是否锁了逻辑。打开 DevTools → Elements 面板,确认目标元素标签上真有 readonly 字样(哪怕写成 readonly="" 或 readonly="anything" 都行)。
-
el.setAttribute('readonly', '')是最稳妥的写法,确保属性真实落进 DOM -
el.readOnly = true多数浏览器能识别,但 SSR 或首屏渲染可能漏掉样式 -
直接写在 HTML 里最可靠 -
依然只读——布尔属性只要出现就生效
:read-only 和 [readonly] 该用哪个?
两者都能选中,但机制不同:
-
input[readonly]是属性选择器:IE8+ 全支持,行为确定,只看 HTML 有没有这个属性 -
input:read-only是伪类:匹配“当前真实只读状态”,JS 动态删掉readonly属性后样式立刻消失 - Firefox 旧版需写
input:-moz-read-only;IE 全系不支持,必须降级用[readonly] - 现代项目若需 JS 响应式切换,可用
@supports selector(:read-only)包一层,老浏览器自动 fallback
只读输入框的典型样式怎么写才不误导用户?
关键不是“灰掉”,而是让用户一眼分清“这是内容,不是被禁用”:
- 背景别太暗:
background-color: #f9fafb(比:disabled的#f4f4f5略亮) - 文字保持原色:
color: #111827(不降权,强调数据真实) - 光标设为
cursor: default,不是not-allowed(后者暗示错误或禁用) - 允许复制:
user-select: text;如需禁止,则加user-select: none - 边框保留结构感:
border: 1px solid #d1d5db,而非border: none
容易被忽略的边界行为
真正卡住人的不是语法,是隐含假设:
-
:read-only不拦截任何事件:用户仍可右键粘贴、Ctrl+A全选、Tab 键停在上面——要禁粘贴得自己监听paste并preventDefault() -
在 Safari 15.4 之前有 bug,:read-only可能不触发,得 fallback 到[readonly] - 只读框仍会接收焦点,查看模式下若不想 Tab 停留,得手动加
tabindex="-1" -
:disabled权重天然高于:read-only,若同时存在,:disabled样式一定生效,且语义冲突(一个提交值,一个不提交)
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











