disabled属性仅对input、textarea、select、button、fieldset等原生表单控件生效,对div、span等无效;它是布尔属性,存在即禁用,js应使用element.disabled = boolean控制,服务端必须校验权限。

disabled属性只对原生表单控件生效
给 div、span、p 或 label 加 disabled 属性完全无效——浏览器直接忽略,既不灰化,也不阻止点击或聚焦。真正支持该属性的只有:input(含 type="text"、"checkbox"、"radio"、"submit" 等)、textarea、select、button、optgroup、option,以及 fieldset。
常见错误现象:<label disabled><input></label> —— label 本身不响应 disabled,关联的 input 依然可点可输;必须直接作用于 input 本体。
disabled="false" 是个典型误解
disabled 是布尔属性,存在即为 true,不存在即为 false。写成 disabled="false" 或 disabled="" 效果一样:都禁用。它不接受字符串值,也不做真假解析。
- ✅ 正确写法:
<input disabled>或<button disabled></button> - ❌ 无效写法:
<input disabled>(照样禁用) - ❌ 错误预期:
el.setAttribute('disabled', 'false')—— 不解除禁用,只是加了个无意义的字符串属性
JS 动态控制必须用 .disabled = boolean
用 element.disabled = true 或 false 是唯一稳定方式。它直接操作 DOM 属性,返回布尔值,兼容所有现代浏览器,且与 HTML5 表单验证行为一致。
容易踩的坑:
- 禁用后焦点不会自动移走,用户按 Tab 可能卡在已禁用元素上;应手动
nextElement.focus() - 若该控件之前有
required,禁用后 HTML5 验证会跳过,但checkValidity()的缓存状态可能残留;建议禁用后调一次reportValidity()清理 - 在 Vue/React 中,仅改 DOM 的
.disabled不同步响应式状态,下次 re-render 会覆盖你的设置;必须同时更新data或state
fieldset disabled 是批量禁用最可靠方案
把一组控件包进 fieldset disabled,比逐个加 disabled 更简洁、语义更准,且浏览器原生递归禁用所有子表单控件(包括嵌套的 fieldset)。
但要注意:
- 子控件显式写
disabled="false"也无效——父级fieldset的禁用状态强制覆盖 -
legend文本不受影响,仍可聚焦、可读取;如需一并“屏蔽”,得额外加 CSS 或 JS 控制 - 部分老浏览器(如 IE11)对禁用
fieldset的默认样式支持不一致,可用fieldset:disabled或[disabled]选择器微调,但别用opacity遮盖——它不改变可访问性状态
服务端永远别信前端禁用了什么。绕过 disabled 只需删掉属性或发个 POST 请求就行。权限判断和字段校验必须落在后端,这是底线。










