:read-only 样式未生效的主因是元素未真正进入只读状态,需确保 HTML 中显式存在 readonly 属性;它不响应 JS 动态设置 readOnly 属性,仅匹配 DOM 中存在的布尔属性。

为什么 :read-only 样式没生效?先确认 HTML 是否真写了 readonly
很多情况下不是 CSS 写错了,而是元素根本没进入 :read-only 状态。浏览器只认 DOM 中显式存在的 readonly 属性(布尔属性),不认 JS 赋值 el.readOnly = true 后没同步写入 HTML 的情况。
-
<input type="text" value="订单号" readonly>✅ 正确 —— 属性存在,:read-only立即命中 -
<input type="text" value="订单号" readonly>❌ 依然只读 —— 布尔属性只要出现就生效,值无效 -
<input type="text" value="订单号" disabled>❌ 不匹配:read-only—— 这是:disabled的事 -
<select readonly>...</select>❌ 完全无效 ——<select></select>不支持readonly属性,伪类自然不触发 -
<div contenteditable="false">...</div>❌ 不适用 ——:read-only只作用于<input>和<textarea></textarea>
input:read-only 和 input[readonly] 用哪个?优先选前者,但得兜底
input:read-only 反映的是“当前真实只读状态”,JS 执行 el.removeAttribute('readonly') 后样式立刻消失;而 input[readonly] 是静态属性匹配,只要属性在 HTML 里就一直生效。
- 现代项目推荐用
input:read-only, textarea:read-only—— 语义更准,且能响应动态状态变化 - 必须兼容 IE 或旧版 Firefox?补上
input:-moz-read-only,或直接降级用input[readonly](它在所有浏览器都可靠) - 别同时写两套规则:如果
input:read-only和input[readonly]都定义了背景色,后者会被前者覆盖(伪类优先级更高),纯属冗余 - 想用
@supports做渐进增强:@supports selector(:read-only) { input:read-only { ... } },老浏览器自动跳过
只读样式怎么设计才不和 :disabled 混淆?关键在视觉意图
用户看到浅灰背景+禁用光标,第一反应是“这东西被锁死了”;但只读字段其实是“内容真实、可复制、会提交”,只是不能改。设计上要拉开感知距离。
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
- 背景色别太暗:
background-color: #f9fafb(比:disabled的#f4f4f5更亮) - 文字颜色保持深灰:
color: #111827(不降权,强调这是有效数据) - 边框保留结构感:
border: 1px solid #d1d5db(不是border: none) - 光标设为
cursor: default(不是not-allowed)——点击无反应比禁止符号更能传达“静态展示” - 加
user-select: text允许复制,对订单号、身份证号这类字段很实用
哪些坑最容易被忽略?聚焦、粘贴、提交行为全都不受 :read-only 控制
:read-only 是纯样式钩子,它不改变任何交互逻辑。这点一旦误解,后续就得补一堆 JS 补丁。
立即学习“前端免费学习笔记(深入)”;
- 元素仍可获得焦点 —— Tab 键会停在上面,查看模式下体验割裂?得手动加
tabindex="-1" - 用户仍可右键粘贴、Ctrl+A 全选、双击选中 —— 要禁粘贴?得监听
paste事件并event.preventDefault() - 表单提交时,
readonly字段的值照常发送 —— 和disabled完全不同,后端别漏收 -
<input type="checkbox" readonly>仍能聚焦、空格切换 —— 视觉上建议统一加pointer-events: none; opacity: 0.8; - Safari 15.4 之前对
input[type="number"]:read-only有匹配 bug,测试时别漏掉这个类型
readonly 属性,前端又不敢擅自加,这种字段只能靠 class 注入或 JS 补全,:read-only 对它完全无感。

















