不是必须但强烈建议用包裹radio组,以建立「问题—选项」语义关系;name必须相同,不可省略,label推荐嵌套写法,value应使用语义化字符串。

radio必须用<fieldset></fieldset>和<legend></legend>包裹吗?
不是必须,但强烈建议。没有<fieldset></fieldset>时,屏幕阅读器无法识别这组<input type="radio">属于同一逻辑单元,用户可能反复听到“未选中,单选按钮”,却不知道它们在回答哪个问题。
语义化核心是建立「问题—选项」关系,<fieldset></fieldset>定义问题域,<legend></legend>就是问题本身:
<fieldset> <legend>您偏好的编程语言?</legend> <label><input type="radio" name="lang" value="js"> JavaScript</label> <label><input type="radio" name="lang" value="py"> Python</label> </fieldset>
-
name属性必须相同,否则浏览器不认为它们互斥 -
<legend></legend>不能省略或留空;用 CSS 隐藏它(如position: absolute; clip: rect(1px, 1px, 1px, 1px))比用aria-label或title更可靠 - 避免把
<legend></legend>写成<h3></h3>—— 它不是标题层级,而是表单语义锚点
label和input的绑定方式:for/id还是嵌套?
两种都合法,但嵌套更简洁、容错更强。用 for/id 时,稍有拼写错误或 ID 重复就会断开关联;而嵌套写法天然保证点击文本即聚焦对应 radio:
<label> <input type="radio" name="theme" value="dark"> 深色模式 </label>
- 嵌套时
<input>必须是<label></label>的直接子元素(不能隔一层<span></span>) - 如果 label 文本需富文本(比如含链接或强调),必须用
for/id方式,否则 HTML 不合法 - 不要给
<input>同时加id又嵌套 —— 多余且可能触发双击行为
如何让未选中的radio也具备可访问性焦点?
默认情况下,键盘 Tab 到第一项后,用方向键切换其他项 —— 这依赖 name 一致且 DOM 顺序连续。但如果中间插入了非 radio 元素(比如说明文字 <p></p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill12116" title="DeepBI DHTML 页面生成器"><img
src="https://img.php.cn/upload/skill/001/246/273/6adaf20d3191a227.jpg" alt="DeepBI DHTML 页面生成器" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill12116" title="DeepBI DHTML 页面生成器">DeepBI DHTML 页面生成器</a>
<p>生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力:
- 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面;
- 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”;
- 提及位于 `apps/console/src/featur</p>
</div>
<a href="/xiazai/skill12116" title="DeepBI DHTML 页面生成器" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div>),方向键会跳过后续选项。
立即学习“前端免费学习笔记(深入)”;
- 所有同组 radio 应保持 DOM 连续,说明文字用
<small></small>或<div role="note"> 包裹并放在 <code><fieldset></fieldset>内部但不打断 radio 流 - 避免用
tabindex="-1"或disabled临时禁用某项;改用aria-disabled="true"并保留 focusable 状态,否则键盘用户无法感知该选项存在 - Chrome 和 Firefox 对 radio 组的方向键支持稳定;Safari 在某些嵌套结构下可能失效 —— 测试时务必用真实键盘操作
- 避免空格或特殊字符(如
"user email"),用短横线分隔:"user-email" - 不要用中文作
value(编码风险 + URL 传输麻烦),但<label></label>文本可以用中文 - 如果选项来自枚举 API,前端应将返回的 ID 映射为语义
value,而不是透传原始数字
value值该用语义字符串还是数字ID?
用语义字符串。后端接收的是 value 字面值,如果存的是 "1" "2",你得额外维护映射表;而 "email" "sms" 直接可读、可调试、可做条件判断。
最常被忽略的是 <legend></legend> 的不可见但不可弃 —— 它不是装饰,是 screen reader 唯一能用来建立上下文的 hook。删掉它,等于把一组 radio 变成一堆孤立的“未选中按钮”。


















