带有 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 角色 grid
、row
和 gridcell
。
但似乎,这些东西只支持基于行的布局而不支持基于列的布局。我们实际上并没有跨越所有车道的行。理论上每个项目都可以有任意高度。
是否有类似 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 一起使用的原因,因为这似乎是许多人认为自然的东西,将网格视为行列表。很难成为语义:/
我们正在构建一个看起来像这样的 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 角色 grid
、row
和 gridcell
。
但似乎,这些东西只支持基于行的布局而不支持基于列的布局。我们实际上并没有跨越所有车道的行。理论上每个项目都可以有任意高度。
是否有类似 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 一起使用的原因,因为这似乎是许多人认为自然的东西,将网格视为行列表。很难成为语义:/