带有 aria 角色网格的基于列的布局

Column based layout with aria role grid

我们正在构建一个看起来像这样的 kanban-board-like 网络应用程序:

所以我们有带物品的泳道。

目前我们有这样的布局:

<ul>
    <ul class="swimlane">
        <li>Item a1</li>
    </ul>
    <ul class="swimlane">
        <li>Item b1</li>
        <li>Item b2</li>
        <li>Item b3</li>
    </ul>
    <ul class="swimlane">
        <li>Item c1</li>
        <li>Item c2</li>
    </ul>
</ul>

所以我们有一个车道列表,它本身就是项目列表。

现在我们正尝试通过允许 table navigation from nvda 使看板导航可访问。例如:clt+alt+left 转到左侧车道中的下一个* 单元格。

为了做到这一点,我们查看了 aria 角色 gridrowgridcell。 但似乎,这些东西只支持基于行的布局而不支持基于列的布局。我们实际上并没有跨越所有车道的行。理论上每个项目都可以有任意高度。

是否有类似 column 的角色或解决方法来实现类似的事情?

* 当然 next 并不总是很容易确定,因为通道可以有不同数量的项目,所以不是每个项目都有左邻居(例如项目 b2 来自示例)

另一种解决方案是手动实现 nvda 的 table-navigation 快捷方式。但似乎 nvda 在它们到达浏览器和我的应用程序之前捕获了这些击键。有解决办法吗?

第三种解决方案是使用与 nvda 类似的快捷方式。但我们想避免这种情况。

模仿 table 的 ARIA 角色无法指定元素应位于哪一列。角色期望 DOM 与真实 [=53] 相似=] 已定义 - 基于行。因此,您必须更改列表的定义方式,使它们基于行而不是基于列。

(注意:您的图片与您的代码示例不符。我下面的示例引用了您的代码示例。)

所以不用

<ul>
    <ul class="swimlane">
        <li>Item a1</li>
    </ul>
    <ul class="swimlane">
        <li>Item b1</li>
        <li>Item b2</li>
        <li>Item b3</li>
    </ul>
    <ul class="swimlane">
        <li>Item c1</li>
        <li>Item c2</li>
    </ul>
</ul>

你需要

<ul>
    <ul>
        <li>Item a1</li>
        <li>Item b1</li>
        <li>Item c1</li>
    </ul>
    <ul>
        <li></li>
        <li>Item b2</li>
        <li>Item c2</li>
    </ul>
    <ul>
        <li></li>
        <li>Item b3</li>
        <li></li>
    </ul>
</ul>

然后您可以使用 table 角色。

注意: ARIA 1.1 中添加了一个新的 table 行。以前,只有 grid 可用。如果您的 table 不是交互式的(即,只是静态文本),那么应该使用 table 角色(和 cell 角色)。如果您的 table 交互式的,例如包含可编辑单元格的电子表格,那么 grid 角色(和 gridcell 角色)应该是用过的。在您的 table 单元格中有一个 link 不被认为是交互式的,即使您可以通过单击 link 来 "interact" 和 table。我使用 "interactive" 这个词来表示单元格是 editable.

<ul role="table">
    <ul role="row">
        <li role="cell">Item a1</li>
        <li role="cell">Item b1</li>
        <li role="cell">Item c1</li>
    </ul>
    <ul role="row">
        <li role="cell"></li>
        <li role="cell">Item b2</li>
        <li role="cell">Item c2</li>
    </ul>
    <ul role="row">
        <li role="cell"></li>
        <li role="cell">Item b3</li>
        <li role="cell"></li>
    </ul>
</ul>

此外,如果您要定义 table,您确实也应该有列 headers。 headers 列可以包含在 role="row"role="rowgroup" 中。 rowgroup 类似于 <thead>,但 rowgroup 目前不会将任何额外的语义信息传递给屏幕阅读器。我使用它是因为它有助于我的专栏 headers 在代码中脱颖而出。

<ul role="table">
    <ul role="rowgroup">
        <li role="columnheader">To Do</li>
        <li role="columnheader">WIP (2)</li>
        <li role="columnheader">Done</li>
    </ul>
    <ul role="row">
        <li role="cell">Item a1</li>
        <li role="cell">Item b1</li>
        <li role="cell">Item c1</li>
    </ul>
    <ul role="row">
        <li role="cell"></li>
        <li role="cell">Item b2</li>
        <li role="cell">Item c2</li>
    </ul>
    <ul role="row">
        <li role="cell"></li>
        <li role="cell">Item b3</li>
        <li role="cell"></li>
    </ul>
</ul>

只是我的两分钱与主要问题没有直接关系,但我认为它会有所帮助:您的代码不会在像 https://validator.w3.org

这样的 w3c 验证器中验证

1) ul 元素只允许 li 或脚本支持元素,如脚本或模板(如先前@unor 在其评论中所述)。您不应将 ul 用作 ul 的直接子代。这是验证器在这种情况下提出的消息:

Content model for element ul: Zero or more li and script-supporting elements.

2) ul 元素不能有角色 grid 或 table。不知道为什么,因为这看起来很有道理,但严格来说,他们做不到。这是验证器将出现的错误:

Error: Bad value table for attribute role on element ul.

例如,您可以在 Mozilla 开发者网站上查看:

或者在这个堆栈溢出主题中谈论这个:

HTML5 nav element vs. role="navigation"

但在您的情况下,如果您将外部 ul 更改为 div,它将验证:

<div role="grid">
    <ul class="swimlane">
        <li>Item a1</li>
    </ul>
    <ul class="swimlane">
        <li>Item b1</li>
        <li>Item b2</li>
        <li>Item b3</li>
    </ul>
    <ul class="swimlane">
        <li>Item c1</li>
        <li>Item c2</li>
    </ul>
</div>

虽然有一个 ul 元素列表,但您最好在 div:

中使用它们的列表
<div role="grid">
 <ul>
  <li>
    <ul class="swimlane">
        <li>Item a1</li>
    </ul>
   </li>
   <li>
    <ul class="swimlane">
        <li>Item b1</li>
        <li>Item b2</li>
        <li>Item b3</li>
    </ul>
   </li>
   <li>
    <ul class="swimlane">
        <li>Item c1</li>
        <li>Item c2</li>
    </ul>
   </li>
</div>

也许标记太冗长,我想知道为什么 ul 不能与角色网格或 table 一起使用的原因,因为这似乎是许多人认为自然的东西,将网格视为行列表。很难成为语义:/