accessibility - 角色=“组”在角色=“树”下是否有效
问题描述
可以说我有一个角色=“树”的元素。在此之下,我有一个元素 role="group",其中包含用于多级树的 role="treeitem" 或 role="group" 元素。
<... role="tree">
<... role="group">
<... role="treeitem">
<... role="treeitem">
<... role="group">
<... role="treeitem">
<... role="treeitem">
这里的问题是可访问性测试工具抱怨角色=“树”的元素必须包含角色=“树项目”的子元素。
查了一下规范,上面写着
Required Owned Elements:
group → treeitem
treeitem
我如何解释这个?树是否应该直接包含树项?树是否可以有一个包含树项的组,但树没有角色“treeitem”的直接子项?
- 编辑 -
这是完整的html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test Tree A11y</title>
</head>
<body>
<div role="main">
<!-- tree contains a group which contains treeitems/group -> treeitems -->
<ul role="tree">
<ul role="group">
<li role="treeitem">Banana</li>
<li role="treeitem">Mango</li>
<ul role="group">
<li role="treeitem">Banana-2</li>
<li role="treeitem">Mango-2</li>
<li role="treeitem">Orange-2</li>
</ul>
</ul>
</ul>
<!-- tree contains a treeitems or groups which contains treeitem -->
<ul role="tree">
<li role="treeitem">Banana</li>
<li role="treeitem">Mango</li>
<ul role="group">
<li role="treeitem">Banana-2</li>
<li role="treeitem">Mango-2</li>
<li role="treeitem">Orange-2</li>
</ul>
</ul>
</div>
</body>
</html>
这里的问题是
具有角色“树”的元素是否必须包含一个或多个“树项”?它可以包含一个包含“treeitems”的“组”吗?
在第一棵树
- 树有一个组,没有角色 treeitem 的直接子级
- 该组具有树项目和一个具有其他树项目的组 这被报告为错误 WCAG 1.3.1。但是,屏幕阅读器似乎工作正常
在第二棵树
- 树有一个树项目和一个有其他树项目的组
在规范中,我无法找到明确的声明,即树必须包含 1 个或多个具有角色树项的 DIRECT 子项。所以我不确定第一棵树是否存在实际的可访问性问题,以及第一棵树是否违反规范。
FWIW,有一个名为 JSTree 的控件使用第一棵树中所示的样式,我正在争论这是否是一个真正的问题。谢谢。
解决方案
简答
虽然将 agroup
作为 a 的直接后代是有效的 HTML 和 WAI-ARIA,tree
但如果它不与相应的treeitem
.
由于 a 的构造role="tree"
方式不同,它是允许的孩子。tree
长答案
role="group"
首先,将 a作为 a 的唯一后代是完全“有效的”(它是有效的标记)role="tree"
。
但是,尽管有效,但它不是推荐的处理方式,并且可能会导致意外行为,具体取决于所使用的屏幕阅读器和浏览器组合。
关键是,在WAI-ARIA 最佳实践文件中,它指出:
每个根节点都包含在具有角色树的元素中,或者由树元素上设置的 aria-owns 属性引用。
因此,当您将顶级节点放入 arole="group"
时,您就违反了此规则,除非您为treeitems
组中的每个节点提供一个 id,然后aria-owns
在role="tree"
. group
无论如何,当你绕过它时,它变得毫无意义。
那么,如果不推荐,为什么允许 arole="group"
作为后代呢?role="tree"
现在您可以争辩说,如果在 agroup
中将 a 作为顶级项目无效,那么一role="tree"
开始就不应该允许它。
role="group"
但是,在顶层允许的原因是您可以将 a 设置treeitem
为打开 agroup
并且这些可以在同一级别(兄弟姐妹)。
我想我可以用一个例子来最好地解释这一点:-
代码示例 1 - 有效,因为group
有父节点treeitem
,因此不充当根节点。
<div id="tree1" role="tree" tabindex="-1">
<div role="treeitem" aria-owns="pizzaGroup" aria-expanded="false" tabindex="0">Pizza Toppings</div>
<ul role="group" id="pizzaGroup">
<li role="treeitem">Cheese</li>
<li role="treeitem">Pepperoni</li>
<li role="treeitem">Onion</li>
</ul>
</div>
在上面的示例中,第一个 div 充当treeitem
并且组由它控制。该关联是用aria-owns
.
它声明它必须包含的原因group -> treeitem
是因为不允许空组。
以上是 a 的一个有效示例role="tree"
,但是如果您可以避免它,我不建议使用该模式,因为对 的支持aria-owns
不是很好。
公认的做法是将group
嵌套在其treeitem
自身中并在整个过程中使用<ul>
和使用<li>
。大多数屏幕阅读器会自动将子节点与父节点关联,而那些仍然无法让用户将关系锻炼为嵌套<ul>
并<li>
得到很好支持的节点。
示例 2 - 使用<ul>
和的推荐模式示例<li>
<ul role="tree">
<li role="treeitem" aria-expanded="false" tabindex="0">
<span>Pizza Toppings</span>
<ul role="group">
<li role="treeitem">Cheese</li>
<li role="treeitem">Pepperoni</li>
<li role="treeitem">Onion</li>
</ul>
</li>
</ul>
希望这能回答为什么可访问性工具抱怨没有 atreeitem
以及为什么您可以将 agroup
作为 a 的子级,tree
但前提是它由关联的treeitem
.
最后的想法
在您的示例中,您没有为树提供标签。不要忘记给主元素添加一个标签role="tree"
,可以是可见标签和aria-labelledby="yourLabelID"
(首选),也可以是aria-label="description of tree"
.
聊天讨论后更新
如果只有指导更清楚!
正如所指出的那样,我对“根节点”的支持信息仍然不清楚,可以评论它仍然可以解释为 agroup
可以是该定义中的根节点。
然而,在树视图的定义中,再加上另一个规则,有足够的清晰度来确认实际上根本不可能将 agroup
算作根节点!
这些是树中节点的定义:
节点 树中的一个项目。
根节点 位于树根的节点;它可能有一个或多个子节点,但没有父节点。
子节点 有父节点的节点;任何不是根节点的节点都是子节点。
父节点 具有一个或多个子节点的节点。它可以打开(展开)或关闭(折叠)。
采取以下规则:
每个子节点都包含在具有角色组的元素中或由其拥有,该元素包含在充当该子节点的父节点的节点中或由其拥有。
因此,在任何情况下都不能将 a 算作group
根节点(或任何节点),它不能有父节点,因此违反了上述规则。
让我解释一下为什么会这样,以及为什么你永远不能将 agroup
视为根节点:
第二次将 a 添加treeitem
到 agroup
以下必须为真:
- 它必须是子节点,因为它不是根节点。
- 每个子节点必须包含或由一个
role="group"
必须包含或拥有的节点包含或拥有,该节点充当新添加的父节点treeitem
。 - 根项目可以没有父节点,我们
group
要求 aparent
有效。
示例 3 - 无效,因为group
没有父节点并且必须充当根节点(它不能)。
<div role="tree">
<!--this group is a root level node and does not have a parent node. -->
<div role="group">
<!--This treeitem must be within a "group" as it is a child node. -->
<!--This means that the "group" above contains it and that means the group above must be owned or controlled by something.-->
<!--This treeitem can never have a parent as root level nodes cannot have a parent node.-->
<div role="treeitem">item</div>
</div>
</div>
就我而言,以下内容也消除了所有歧义:
每个作为树节点的元素都有角色 treeitem。
所以我最初的前提是正确的,为什么 agroup
被允许作为 a 中的顶级项目tree
。
事实上,更清楚的是,一个组永远不可能是根节点(或者根本不可能是一个节点!),并且 a可以作为 a 的直接后代出现role="treeitem group"
的唯一原因是它是否是与 a 的兄弟正如我最初所说的那样控制它(它是父级)。group
tree
treeitem
推荐阅读
- c# - Problem with Automata simple conditional statements in C#
- c - Cannot follow tutorial (https://developer.gnome.org/anjuta-build-tutorial/stable/create-autotools.html.en)
- json - Swift 4 - 无法使用“(可编码)”类型的参数列表调用“编码”
- python - PYSPARK:CX_ORACLE.InterfaceError:不是查询
- python - SimpleITK not working with any data type, be it 3D or 2D
- mysql - 基于通配符替换字符串的 SQL 查询
- r - R比较来自一个数据帧的值与来自另一个数据帧的值
- apache - 使用flume在两个单独的表中写入hive仓库目录中的数据
- javascript - 动态改变 SVG 光标
- swift - 为什么我的操场在 NSRange() 上崩溃