如何在HTML中为单选按钮网格添加语义化且无障碍的标签?
语义化网格表单解决方案
针对你需要的关联行(问题)和列(选项值)的语义化表单,这里提供一个兼顾视觉布局和无障碍访问的实现方案:
核心思路
- 用
<fieldset>+<legend>处理每行问题的分组,让屏幕阅读器识别出单选按钮属于哪个问题; - 给顶部的列标题设置唯一ID,通过
aria-labelledby属性将每个单选按钮同时关联到问题标签(<legend>)和对应的列标题,实现双重标签关联; - 用CSS Grid保持你需要的网格布局效果。
完整代码示例
HTML
<form class="question-grid"> <!-- 顶部列标题 --> <div class="col-header"></div> <div class="col-header" id="col-neg2">-2</div> <div class="col-header" id="col-neg1">-1</div> <div class="col-header" id="col-zero">+0</div> <div class="col-header" id="col-pos1">+1</div> <div class="col-header" id="col-pos2">+2</div> <!-- 第一题 --> <fieldset class="question-row"> <legend id="q1">Question1</legend> <input type="radio" name="question1" value="-2" aria-labelledby="q1 col-neg2"> <input type="radio" name="question1" value="-1" aria-labelledby="q1 col-neg1"> <input type="radio" name="question1" value="0" aria-labelledby="q1 col-zero"> <input type="radio" name="question1" value="1" aria-labelledby="q1 col-pos1"> <input type="radio" name="question1" value="2" aria-labelledby="q1 col-pos2"> </fieldset> <!-- 第二题 --> <fieldset class="question-row"> <legend id="q2">Question2</legend> <input type="radio" name="question2" value="-2" aria-labelledby="q2 col-neg2"> <input type="radio" name="question2" value="-1" aria-labelledby="q2 col-neg1"> <input type="radio" name="question2" value="0" aria-labelledby="q2 col-zero"> <input type="radio" name="question2" value="1" aria-labelledby="q2 col-pos1"> <input type="radio" name="question2" value="2" aria-labelledby="q2 col-pos2"> </fieldset> <!-- 第三题 --> <fieldset class="question-row"> <legend id="q3">Question3</legend> <input type="radio" name="question3" value="-2" aria-labelledby="q3 col-neg2"> <input type="radio" name="question3" value="-1" aria-labelledby="q3 col-neg1"> <input type="radio" name="question3" value="0" aria-labelledby="q3 col-zero"> <input type="radio" name="question3" value="1" aria-labelledby="q3 col-pos1"> <input type="radio" name="question3" value="2" aria-labelledby="q3 col-pos2"> </fieldset> </form>
CSS
.question-grid { display: grid; grid-template-columns: auto repeat(5, 1fr); max-width: 20em; gap: 0.5em; /* 可选,增加间距提升可读性 */ } .col-header { text-align: center; font-weight: bold; /* 突出表头 */ } .question-row { display: contents; /* 让fieldset的子元素直接参与网格布局,避免fieldset创建额外容器 */ border: none; /* 移除默认fieldset边框 */ margin: 0; padding: 0; } .question-row legend { grid-column: 1; /* 强制legend放在第一列 */ text-align: left; padding: 0; margin: 0; } .question-row input[type="radio"] { justify-self: center; /* 单选按钮居中 */ }
关键细节说明
<fieldset>+<legend>:天然的表单分组语义,屏幕阅读器会先读出<legend>的内容,再依次播报组内的单选按钮;aria-labelledby:属性值可以同时填多个ID,屏幕阅读器会按顺序读出这些元素的文本内容,比如第一个单选按钮会被读成“Question1 -2”,完美关联行和列的标签;display: contents:让<fieldset>不生成独立的盒子,其子元素直接融入网格布局,保证视觉效果和你原来的需求一致;- 列标题的ID:确保每个列标题有唯一ID,方便单选按钮准确关联。
内容的提问来源于stack exchange,提问作者user108471
相关产品推荐
相关产品推荐

