html - 可访问性:如何正确地为一个 INPUT 项目使用多个 LABEL 元素(通过 ARIA 等)?
问题描述
我有一个两侧的移动菜单抽屉,它依赖于一个隐藏的复选框来在其两侧之间切换/切换。
有两个 LABEL 元素,一个位于菜单抽屉的每一侧。每个 LABEL 通过其 FOR 属性引用隐藏的 INPUT 复选框的 ID。因此,单击显示的 LABEL 会检查 INPUT 复选框并导致菜单切换侧面(通过 CSS)。HTML的一个提炼是:
<ul class=main-menu>
<li>
<input id=toggle-drawer type=checkbox title="hidden checkbox">
<label for=toggle-drawer>See Sub Menu</label>
<ul class=sub-menu>
<li>
<label for=toggle-drawer>See Main Menu</label>
</li>
<li>Sub-menu item 1</li>
<li>Sub-menu item 2</li>
<li>Sub-menu item 3</li>
</ul>
</li>
<li>Main Menu item 1</li>
<li>Main Menu item 2</li>
<li>Main Menu item 3</li>
</ul>
事实上,拥有多个引用同一个输入项的标签是完全有效的 HTML。
见https://www.w3.org/TR/html401/interact/forms.html#h-17.9.1:
“通过 for 属性创建多个引用,可以将多个 LABEL 与同一个控件相关联。”
但是,WebAIM WAVE(Web 可访问性评估工具)浏览器扩展将这两个标签标记为错误,并指出,
“一个表单控件最多应该有一个关联的标签元素。如果多个标签元素与控件关联,辅助技术可能无法读取适当的标签。”
作为补救措施,它继续指出:
“如果需要多个表单标签,请使用 aria-labelledby。”
aria-labelledby 似乎不适用于我的情况,因为它会放在由 DIV 等引用的 INPUT 项目上。
我可以使用 ARIA 或类似的标记方法来满足此可访问性审核吗?我不想改变我的 HTML 结构。
解决方案
虽然它是完全有效的 HTML,但有两个标签会导致 NVDA 和其他屏幕阅读器出现问题,它只能读取一个标签。
这就是为什么 WAVE 建议您使用aria-labelledby
它,因为它旨在获取多个元素并可以组合它们(按您列出它们的顺序)。
在 上使用 this 是完全有效的input
,还要注意这aria-labelledby
将覆盖任何关联的<label>
元素使用for="id"
您可以做的一件事是使用不太常用aria-describedby
的标签来关联第二个标签并确保阅读顺序正确。
在下面的示例中,它将读取“查看主菜单,查看子菜单”,因为它将<label for="toggle-drawer">
首先读取,然后使用aria-describedby="toggle-drawer-label"
添加附加信息。
唯一的缺点是它可能会读取<label>
和describedby
标签之间的输入信息。
<ul class=main-menu>
<li>
<input id="toggle-drawer" aria-describedby="toggle-drawer-label" type=checkbox title="hidden checkbox">
<label id="toggle-drawer-label">See Sub Menu</label>
<ul class=sub-menu>
<li>
<label for="toggle-drawer">See Main Menu</label>
</li>
<li>Sub-menu item 1</li>
<li>Sub-menu item 2</li>
<li>Sub-menu item 3</li>
</ul>
</li>
<li>Main Menu item 1</li>
<li>Main Menu item 2</li>
<li>Main Menu item 3</li>
</ul>
推荐的方式
我建议简单地使用aria-labelledby="label1 label2"
,因为这是公认的方法,并且会产生最一致的结果,显然这意味着您需要id
为两个标签添加属性,这样就可以进行权衡。
请注意,使用两个标签上aria-labelledby="label1 label2"
的字段并将其关联起来for="toggle-drawer"
具有正确链接标签的额外好处,以便您可以单击任一标签并将焦点放在<input>
.
推荐阅读
- python - 使用beautifulsoup python在跨度类HTML中刮取值
- winapi - 如何使用我自己的清单文件并将其嵌入到使用 Visual Studio 2017 的可执行文件中?
- javascript - 为什么返回在当前函数之外定义的函数不创建闭包?
- scala - ScalaZ:缺少单子转换器的基本 flatMap 方法?(子平面图)
- jquery - 表单提交后HTML页面不断重置
- java - Spring Cloud Config Server - 连接 github 的用户名和密码
- mysql - 将特定的 CONCAT MYSQL 转换为 PDO Laravel
- flutter - Get values of dynamic list of widgets - flutter
- matlab - 当内部 2 个 for 循环参数随着第一个 main for 循环的每次迭代而变化时,是否可以矢量化 3 个嵌套的 for 循环(总共 3 个)?
- amazon-web-services - 如何将(Firebase)云函数与 AWS Lambda 连接?