单选按钮组必须用不同 name 属性实现互斥,性别用 name="gender"、状态用 name="status";需配 label[for] 和 fieldset/legend 保障可访问性;未选时字段不提交,后端须处理缺失键。

单选按钮组必须用相同 name 才能互斥
浏览器靠 name 属性识别一组单选按钮(<input type="radio">)是否属于同一逻辑字段。如果性别和状态各自独立,它们的 name 必须不同;否则选中一个会意外取消另一个字段的选项。
常见错误是复制粘贴时漏改 name,比如两个组都写成 name="gender",结果点“启用”时,“女”自动被取消 —— 这不是 bug,是浏览器按规范行为。
- 性别组用
name="gender",值设为"male"/"female"/"other" - 状态组用
name="status",值设为"active"/"inactive" - 每个
input必须配<label></label>,且用for指向id,否则点击文字无法触发选择
checked 属性只对初始默认值有效
HTML 中的 checked 是布尔属性,仅控制页面首次加载时哪个选项被选中。它不会响应后续 JS 修改或表单重置以外的状态变化。如果你用 JS 动态设置选中项,得操作 element.checked = true,而不是改 HTML 属性。
典型场景:编辑已有用户数据时,需要根据后端返回的 gender 和 status 值,用 JS 找到对应 input 并设 checked = true。
- 服务端返回
{"gender": "female", "status": "inactive"} - JS 查找:
document.querySelector('input[name="gender"][value="female"]').checked = true - 注意:若值不存在(如空字符串或 null),不设
checked,避免误选
无障碍与语义化不能只靠视觉分组
仅用 CSS 把两组单选按钮在视觉上分开(比如加边框、间距),对屏幕阅读器无效。辅助技术依赖 HTML 结构识别字段含义。
正确做法是用 <fieldset></fieldset> + <legend></legend> 显式包裹每组,并确保 <legend></legend> 文本准确描述该组用途。
- 性别组外层:
<fieldset> <legend>性别</legend>...</fieldset> - 状态组外层:
<fieldset> <legend>账户状态</legend>...</fieldset> - 不要用
<div> 模拟分组,这会让 VoiceOver 或 NVDA 读不出逻辑关系 <li> <code><legend></legend>内容应简洁明确,避免“请选择”这类冗余词 - 前端可加 JS 校验:
document.querySelectorAll('input[name="gender"]:checked').length === 0 - 后端解析时,应对缺失的
gender/status做显式判断,而非直接取值 - 不推荐用 hidden input 补默认值(如
<input type="hidden" name="gender" value="">),会干扰原生表单逻辑
提交时后端接收不到值?检查空值与默认逻辑
单选按钮组如果没有一项带 checked,整个 name 不会出现在表单提交数据中(GET 查询串或 POST body 里直接消失)。这意味着后端收到的可能是空字段,而非显式的 null 或 ""。
尤其当表单允许部分字段为空时,容易忽略这点:比如新增用户没选性别,后端就收不到 gender 键,但更新用户时可能期望它存在。
最易被忽略的是:多个单选组共用一个表单时,某组未选,会导致整个字段从请求中“静默消失”,调试时看不到报错,只看到后端逻辑异常。











