HTML单选按钮不支持readonly属性,必须用disabled实现禁用;若需保留提交值,则须结合JavaScript拦截事件并服务端校验。

HTML单选按钮(<input type="radio">)不支持 readonly 属性
直接给 <input type="radio"> 加 readonly 属性完全无效——浏览器会忽略它,用户依然能点击切换选项。这是 HTML 规范明确限定的:readonly 只对文本类可编辑控件(如 <input type="text">、<textarea>)生效,对 radio、checkbox、file 等类型无意义。
必须用 disabled 实现“视觉锁定 + 交互禁用”
disabled 是唯一可靠的方式,但它会带来两个关键副作用,必须提前确认是否可接受:
- 表单提交时,该 radio 组的
name值不会发送(哪怕某个选项已被选中) - 元素无法获得焦点、不能被选中、右键复制失效、默认样式变灰且弱化
示例写法:
<input type="radio" name="status" value="active" disabled checked> <label>启用</label> <input type="radio" name="status" value="inactive" disabled> <label>停用</label>
注意:如果后端需要这个字段的值,请在提交前用隐藏域补上,例如:
立即学习“前端免费学习笔记(深入)”;
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
<input type="hidden" name="status" value="active">
想保留提交值但禁用交互?得靠 JavaScript 拦截
当业务要求“值必须提交 + 用户不能改选项”时,disabled 不适用,只能用 JS 阻断事件并视觉提示:
- 监听
click和change,调用e.preventDefault() - 设置
tabindex="-1"防止键盘切换 - 加 CSS 样式(如
pointer-events: none或opacity: 0.7)强化只读感知 - 务必在服务端校验该字段未被篡改——前端拦截可被绕过
简短示例:
<input type="radio" name="priority" value="high" id="p1" checked>
<label for="p1">高</label>
<script>
document.querySelectorAll('input[type="radio"][name="priority"]').forEach(r => {
r.addEventListener('click', e => e.preventDefault());
r.tabIndex = -1;
});
</script>
MVC/Razor 中常见错误写法
在 ASP.NET MVC 的 Razor 视图里,容易误写成:
@Html.RadioButtonFor(m => m.Status, "active", new { @readonly = "readonly" })
这生成的是 readonly="readonly" 属性,对 radio 完全无效。正确做法是:
- 用
disabled = "disabled"(如果允许丢值) - 或改用
new { @class = "readonly-radio" }配合上面的 JS 方案 - 别依赖框架自动处理,radio 的只读逻辑必须手动控制
真正难的不是加个属性,而是想清楚:你到底要锁住交互,还是要锁住值参与流程——这两个目标在 radio 上天然冲突,必须用组合手段补足。


















