首页 > 解决方案 > 角色=“组”在角色=“树”下是否有效

问题描述

可以说我有一个角色=“树”的元素。在此之下,我有一个元素 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”的“组”吗?

在第一棵树

在第二棵树

在规范中,我无法找到明确的声明,即树必须包含 1 个或多个具有角色树项的 DIRECT 子项。所以我不确定第一棵树是否存在实际的可访问性问题,以及第一棵树是否违反规范。

FWIW,有一个名为 JSTree 的控件使用第一棵树中所示的样式,我正在争论这是否是一个真正的问题。谢谢。

标签: accessibilitywai-ariaaccessibility-insights

解决方案


简答

虽然将 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-ownsrole="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 的兄弟正如我最初所说的那样控制它(它是父级)。grouptreetreeitem


推荐阅读