HTML中readonly是布尔属性,存在即生效,正确写法为<input readonly>;JS中须用readOnly(驼峰)属性控制;CSS推荐:read-only伪类;<select>等元素不支持readonly。

直接写 readonly 就生效,别赋值也别写 false
HTML 中 readonly 是布尔属性,只要存在就启用只读,不需要任何值。写成 readonly="true" 或 readonly="false" 都是错的:readonly="false" 反而会触发只读(因为属性存在即生效),readonly="true" 虽能运行但不符合规范,某些校验工具或 SSR 场景会报错。
正确写法只有这一种:<input type="text" value="不可改" readonly><textarea readonly>只读文本</textarea>
- 对
<input type="date">、<input type="datetime-local">等现代类型,多数浏览器支持readonly,但 iOS Safari 会忽略——得额外监听click并event.preventDefault() -
<select>、<input type="checkbox">、<button>上加readonly完全无效,浏览器直接忽略 -
<input type="hidden">加readonly没意义,它本来就不能输入
readOnly(驼峰)才是 JS 动态控制的正确写法
用 JavaScript 切换只读状态时,必须操作 DOM 属性 readOnly(注意大小写),不是 readonly。设 el.setAttribute('readonly', '') 在旧版 Safari 或动态渲染场景下可能不生效。
正确操作:
立即学习“前端免费学习笔记(深入)”;
inputEl.readOnly = true; → 设为只读inputEl.readOnly = false; → 取消只读if (inputEl.readOnly) { ... } → 检查状态(返回布尔值)
- 别用
getAttribute('readonly')判断,它返回null或字符串,不可靠 - 如果同时设置了
disabled,它会覆盖readOnly,此时只读失效 - React 中必须写
readOnly={true}(驼峰+布尔值),写readonly会被忽略且控制台警告
:read-only 伪类比 [readonly] 更精准
CSS 中优先用 :read-only 伪类,它只匹配真正处于只读状态的元素(包括 JS 动态设置的),而 [readonly] 只匹配 HTML 中显式写了该属性的元素。
推荐样式示例:
input:read-only,<br>textarea:read-only {<br> background-color: #f9f9f9;<br> cursor: default;<br> border-color: #ddd;<br>}
- 别只靠背景色区分,加
cursor: default和轻微边框变化更稳妥 - 避免用
opacity: 0.7,影响可读性;也别设tabindex="-1",否则键盘用户无法聚焦查看 - 旧浏览器不支持
:read-only?用 JS 检测,不支持时给元素加 class(如readonly-polyfill)再写对应样式
contenteditable 元素不能用 readonly
readonly 对 contenteditable="true" 的 <div> 或 <p> 完全无效。必须显式关闭编辑能力:
- 最直接:设
contenteditable="false" - 视觉屏蔽(不防 JS):
pointer-events: none; user-select: none; - 防御性拦截:监听
beforeinput或keydown并event.preventDefault(),同时确保tabindex="-1"避免键盘聚焦 - 别用
contenteditable="plaintext-only"—— 这不是标准属性,兼容性无保障
真正麻烦的是混合场景:比如字段初始只读,权限变化后需可编辑。这时光切 readOnly 不够,还得同步处理 tabindex、焦点逻辑和事件监听器,否则会出现“能聚焦却输不了”的卡顿体验。



















