在制作表单时,你是否对单选按钮和复选框组的 label 该如何处理感到犹豫? 尤其是该如何为整个分组设置标签,以及该如何处理 for 属性,常常令人困惑。
本文将梳理此类分组的标签设置方法,并介绍具体的实现方式。
常见做法及其问题
将 for 指向第一个选项
这是针对单选按钮和复选框组的一种做法,即将<label>该组的for属性指向第一个选项。
例如,可以使用如下代码。
<div class="form-group">
<label for="fruit-apple">好きな果物</label>
<div>
<label><input type="radio" id="fruit-apple" name="fruit" value="apple">りんご</label>
<label><input type="radio" name="fruit" value="orange">みかん</label>
<label><input type="radio" name="fruit" value="banana">バナナ</label>
</div>
</div>
从外观上看似乎没有问题,但在屏幕阅读器中,“喜欢的水果”这一标签只会与第一个单选按钮关联,因此整个分组无法被正确识别。
未指定 for
<div class="form-group">
<label>好きな果物</label>
<div>
<label><input type="radio" name="fruit" value="apple">りんご</label>
<label><input type="radio" name="fruit" value="orange">みかん</label>
<label><input type="radio" name="fruit" value="banana">バナナ</label>
</div>
</div>
这种方法无法清楚地表明标签与哪个元素相关联。尤其是对于使用屏幕阅读器的用户来说,哪个选项与标签对应并不明确。
可以采用的改进方案
使用 role 属性进行分组,并通过 aria-labelledby 添加标签
该方法是将单选按钮和复选框分别用 role="radiogroup" 或 role="group" 进行分组,并通过 aria-labelledby 关联由 ID 指定的标签元素。这样可以明确告知屏幕阅读器,“喜欢的水果”这一标签适用于整个分组。
单选按钮
<div class="form-group">
<span id="fruit-group">好きな果物</span>
<div>
<div role="radiogroup" aria-labelledby="fruit-group">
<label><input type="radio" name="fruit" value="apple">りんご</label>
<label><input type="radio" name="fruit" value="orange">みかん</label>
<label><input type="radio" name="fruit" value="banana">バナナ</label>
</div>
</div>
</div>
复选框
<div class="form-group">
<span id="fruit-group">好きな果物</span>
<div>
<div role="group" aria-labelledby="fruit-group">
<label><input type="checkbox" name="fruit" value="apple">りんご</label>
<label><input type="checkbox" name="fruit" value="orange">みかん</label>
<label><input type="checkbox" name="fruit" value="banana">バナナ</label>
</div>
</div>
</div>
使用 <fieldset>fieldset 和 <legend>legend 的方法
另一种方法是使用 <fieldset>fieldset 和 <legend>legend。这种方式基于 HTML 语义,无需添加特殊属性或 role,即可让整个分组被正确识别。
以下示例中,使用 <fieldset>fieldset 包裹单选按钮分组,并使用 <legend>legend 作为标签。
※ 注意:设计上可能需要将标签与输入项并排布局。此时若要将 fieldset 设为 display: contents;,由于部分浏览器会将 legend 从无障碍功能树中移除,因此不建议这样做。若为了对齐布局而用 CSS 强行调整,导致无障碍性受损,这样做并不可取。
<div class="form-group">
<fieldset>
<legend>好きな果物</legend>
<div>
<label><input type="radio" name="fruit" value="apple">りんご</label>
<label><input type="radio" name="fruit" value="orange">みかん</label>
<label><input type="radio" name="fruit" value="banana">バナナ</label>
</div>
</fieldset>
</div>
总结
对单选按钮或复选框组进行标签设置,可整理为以下几种方式。
使用 role 属性和 aria-labelledby 的方法
- 如需定制,也可灵活应对
- 结合 role="group" 显式设置分组标签
使用 <fieldset>fieldset 和 <legend>legend 的方法
- 基于语义的标准方法
- 可实现更稳健且更易访问的实现方式
- 根据布局不同,可能存在无障碍方面的问题
根据设计和需求,无论选择哪种方法,都能实现适当的无障碍性。
从语义角度来看,<fieldset>与<legend>更为合适,但在联系表单等场景中,考虑到整体布局结构,role 属性与 aria-labelledby 的组合可能更便于使用。
网页无障碍还有很多值得深入的内容!
从 DTP 进入 Web 领域,不知不觉间,标记、前端、项目指导、无障碍样样精通的“技术仙人”。自 Liberogic 创业初期起就身兼多职,如今已是公司内的活字典般的存在。最近沉迷于用提示词提升效率的探索:“无障碍支持,能不能更多地依靠 AI 呢?”技术与思考仍在不断进化中。
二俣 歩
IAAP认证网页无障碍专家(WAS) / 标记工程师 / 前端工程师 / 网页总监