Colgroup for complex table with three levels of headers
Colgroup for complex table with three levels of headers
给定一个 table 这样的:
(HTML-code):
<table>
<thead>
<tr>
<th>H1-A</th>
<th colspan="3">H1-B</th>
<th colspan="3">H1-C</th>
</tr>
<tr>
<th>H2-A</th>
<th colspan="2">H2-B</th>
<th>H2-C</th>
<th colspan="3">H2-D</th>
<th colspan="3">H2-E</th>
</tr>
<tr>
<th height="10">H3-A</th>
<th>H3-B</th>
<th>H3-C</th>
<th>H3-D</th>
<th>H3-E</th>
<th>H3-F</th>
<th>H3-G</th>
<th>H3-I</th>
<th>H3-J</th>
<th>H3-K</th>
</tr>
</thead>
<tbody>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
</tbody>
</table>
是否可以用colgroup-tag标记headers这个table?换句话说:
列组可以用于 multi-row headers 吗?
我需要标记 headers 以实现可访问性目的,这似乎是此类 table 的唯一选择,因为 headers-attribute 似乎有 poor screenreader-support
我的理解是,你可以用“colgroup”元素来标识列组,但是你不能用它们指定这个header结构,因为“colgroup”元素不能包含其他“colgroup”元素。
我的实验使我得出结论,屏幕阅读器的支持比您描述的更差:支持很差,而且不仅对“headers”属性,而且对 tables作为一个整体,除了最简单的,而且对于最简单的tables来说甚至都不是很好。
更糟糕的是,有时屏幕阅读器确实会为单元格宣布 headers,并宣布错误的 headers(当 table 被正确标记时),导致用户认为某些东西属于一个类别,而实际上它属于另一个类别。
如果我想在能力和 assistive-technology 范围内提供可靠的可理解性,我可能会将数据渲染为 tables,但我会在一些更广泛支持(虽然较少简约) 格式,例如标题和段落。
前言
这并不像我想象的那么简单,我尝试了很多技术,例如典型的 colgroup
,然后我什至尝试了 headers
attribute,它允许您定义 headers 通过 ID。
经过一番搜索,我发现了这个 example page where someone had tried 3 level column headers (example 3),他们遇到了类似的问题。
经过一番修改后,我确实设法得到了一些可行且看起来不错的东西,但它需要在其他屏幕上进行更多测试 readers,因为我的电脑上只有 NVDA 和 JAWS (目前没有时间测试所有 browser-screen reader 组合)。
可能的解决方案
与任何事情一样,如果我无法使语义元素起作用并且无法使 WAI-ARIA 起作用,那么我会求助于我们的老朋友 aria-hidden
和 visually hidden text。
我所做的是从屏幕 reader 中完全隐藏 table 中的前两 header 行,然后使用视觉隐藏文本将信息添加回第 3 级headers.
例如,对于第 10 列,我在“H3-K”之前添加“H1-C、H2-E”。
<th scole="col"><span class="visually-hidden">H1-C, H2-E,</span>H3-K</th>
通过这种方式,屏幕 reader 用户可以有效地看到普通的 10 列 table,这很容易导航,但所有相关的 header 信息都会被读出。
例如第一个单元格读作
row 2 H1-A, H2-A,H3-A column 1 data 1a
你显然想要构建一些解决方案(最好是在服务器上,但在紧要关头使用 JS 会被接受table)自动执行此操作以避免出现任何错误。
这不是一个理想的解决方案但这是我能想到的最好的解决方案,也是我会做的,因为至少所有相关信息都会显示在屏幕上reader 用户。
警告: 如果我可以自动执行该过程,我只会使用该解决方案,如果我不能为每列自动生成视觉隐藏文本,我会 什么都不做 并保持 table 原样,因为这里的错误可能比单独留下 table 更不容易发现。
例子
table{
width: 100%;
}
th{
text-align: center;
}
th, td{
border: 1px solid #333;
}
.visually-hidden {
border: 0;
padding: 0;
margin: 0;
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */
clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/
white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
}
<table>
<thead>
<tr aria-hidden="true">
<th colspan="4">H1-A</th>
<th colspan="3">H1-B</th>
<th colspan="3">H1-C</th>
</tr>
<tr aria-hidden="true">
<th>H2-A</th>
<th colspan="2">H2-B</th>
<th>H2-C</th>
<th colspan="3">H2-D</th>
<th colspan="3">H2-E</th>
</tr>
<tr>
<th scole="col" height="10"><span class="visually-hidden">H1-A, H2-A,</span>H3-A</th>
<th scole="col"><span class="visually-hidden">H1-A, H2-B,</span>H3-B</th>
<th scole="col"><span class="visually-hidden">H1-A, H2-B,</span>H3-C</th>
<th scole="col"><span class="visually-hidden">H1-A, H2-C,</span>H3-D</th>
<th scole="col"><span class="visually-hidden">H1-B, H2-D,</span>H3-E</th>
<th scole="col"><span class="visually-hidden">H1-B, H2-D,</span>H3-F</th>
<th scole="col"><span class="visually-hidden">H1-B, H2-D,</span>H3-G</th>
<th scole="col"><span class="visually-hidden">H1-C, H2-E,</span>H3-I</th>
<th scole="col"><span class="visually-hidden">H1-C, H2-E,</span>H3-J</th>
<th scole="col"><span class="visually-hidden">H1-C, H2-E,</span>H3-K</th>
</tr>
</thead>
<tbody>
<tr>
<td>data 1a</td>
<td>data 2a</td>
<td>data 3a</td>
<td>data 4a</td>
<td>data 5a</td>
<td>data 6a</td>
<td>data 7a</td>
<td>data 8a</td>
<td>data 9a</td>
<td>data 10a</td>
</tr>
<tr>
<td>data 1b</td>
<td>data 2b</td>
<td>data 3b</td>
<td>data 4b</td>
<td>data 5b</td>
<td>data 6b</td>
<td>data 7b</td>
<td>data 8b</td>
<td>data 9b</td>
<td>data 10b</td>
</tr>
</tbody>
</table>
给定一个 table 这样的:
(HTML-code):
<table>
<thead>
<tr>
<th>H1-A</th>
<th colspan="3">H1-B</th>
<th colspan="3">H1-C</th>
</tr>
<tr>
<th>H2-A</th>
<th colspan="2">H2-B</th>
<th>H2-C</th>
<th colspan="3">H2-D</th>
<th colspan="3">H2-E</th>
</tr>
<tr>
<th height="10">H3-A</th>
<th>H3-B</th>
<th>H3-C</th>
<th>H3-D</th>
<th>H3-E</th>
<th>H3-F</th>
<th>H3-G</th>
<th>H3-I</th>
<th>H3-J</th>
<th>H3-K</th>
</tr>
</thead>
<tbody>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
<td>data</td>
</tr>
</tbody>
</table>
是否可以用colgroup-tag标记headers这个table?换句话说:
列组可以用于 multi-row headers 吗?
我需要标记 headers 以实现可访问性目的,这似乎是此类 table 的唯一选择,因为 headers-attribute 似乎有 poor screenreader-support
我的理解是,你可以用“colgroup”元素来标识列组,但是你不能用它们指定这个header结构,因为“colgroup”元素不能包含其他“colgroup”元素。
我的实验使我得出结论,屏幕阅读器的支持比您描述的更差:支持很差,而且不仅对“headers”属性,而且对 tables作为一个整体,除了最简单的,而且对于最简单的tables来说甚至都不是很好。
更糟糕的是,有时屏幕阅读器确实会为单元格宣布 headers,并宣布错误的 headers(当 table 被正确标记时),导致用户认为某些东西属于一个类别,而实际上它属于另一个类别。
如果我想在能力和 assistive-technology 范围内提供可靠的可理解性,我可能会将数据渲染为 tables,但我会在一些更广泛支持(虽然较少简约) 格式,例如标题和段落。
前言
这并不像我想象的那么简单,我尝试了很多技术,例如典型的 colgroup
,然后我什至尝试了 headers
attribute,它允许您定义 headers 通过 ID。
经过一番搜索,我发现了这个 example page where someone had tried 3 level column headers (example 3),他们遇到了类似的问题。
经过一番修改后,我确实设法得到了一些可行且看起来不错的东西,但它需要在其他屏幕上进行更多测试 readers,因为我的电脑上只有 NVDA 和 JAWS (目前没有时间测试所有 browser-screen reader 组合)。
可能的解决方案
与任何事情一样,如果我无法使语义元素起作用并且无法使 WAI-ARIA 起作用,那么我会求助于我们的老朋友 aria-hidden
和 visually hidden text。
我所做的是从屏幕 reader 中完全隐藏 table 中的前两 header 行,然后使用视觉隐藏文本将信息添加回第 3 级headers.
例如,对于第 10 列,我在“H3-K”之前添加“H1-C、H2-E”。
<th scole="col"><span class="visually-hidden">H1-C, H2-E,</span>H3-K</th>
通过这种方式,屏幕 reader 用户可以有效地看到普通的 10 列 table,这很容易导航,但所有相关的 header 信息都会被读出。
例如第一个单元格读作
row 2 H1-A, H2-A,H3-A column 1 data 1a
你显然想要构建一些解决方案(最好是在服务器上,但在紧要关头使用 JS 会被接受table)自动执行此操作以避免出现任何错误。
这不是一个理想的解决方案但这是我能想到的最好的解决方案,也是我会做的,因为至少所有相关信息都会显示在屏幕上reader 用户。
警告: 如果我可以自动执行该过程,我只会使用该解决方案,如果我不能为每列自动生成视觉隐藏文本,我会 什么都不做 并保持 table 原样,因为这里的错误可能比单独留下 table 更不容易发现。
例子
table{
width: 100%;
}
th{
text-align: center;
}
th, td{
border: 1px solid #333;
}
.visually-hidden {
border: 0;
padding: 0;
margin: 0;
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */
clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/
white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
}
<table>
<thead>
<tr aria-hidden="true">
<th colspan="4">H1-A</th>
<th colspan="3">H1-B</th>
<th colspan="3">H1-C</th>
</tr>
<tr aria-hidden="true">
<th>H2-A</th>
<th colspan="2">H2-B</th>
<th>H2-C</th>
<th colspan="3">H2-D</th>
<th colspan="3">H2-E</th>
</tr>
<tr>
<th scole="col" height="10"><span class="visually-hidden">H1-A, H2-A,</span>H3-A</th>
<th scole="col"><span class="visually-hidden">H1-A, H2-B,</span>H3-B</th>
<th scole="col"><span class="visually-hidden">H1-A, H2-B,</span>H3-C</th>
<th scole="col"><span class="visually-hidden">H1-A, H2-C,</span>H3-D</th>
<th scole="col"><span class="visually-hidden">H1-B, H2-D,</span>H3-E</th>
<th scole="col"><span class="visually-hidden">H1-B, H2-D,</span>H3-F</th>
<th scole="col"><span class="visually-hidden">H1-B, H2-D,</span>H3-G</th>
<th scole="col"><span class="visually-hidden">H1-C, H2-E,</span>H3-I</th>
<th scole="col"><span class="visually-hidden">H1-C, H2-E,</span>H3-J</th>
<th scole="col"><span class="visually-hidden">H1-C, H2-E,</span>H3-K</th>
</tr>
</thead>
<tbody>
<tr>
<td>data 1a</td>
<td>data 2a</td>
<td>data 3a</td>
<td>data 4a</td>
<td>data 5a</td>
<td>data 6a</td>
<td>data 7a</td>
<td>data 8a</td>
<td>data 9a</td>
<td>data 10a</td>
</tr>
<tr>
<td>data 1b</td>
<td>data 2b</td>
<td>data 3b</td>
<td>data 4b</td>
<td>data 5b</td>
<td>data 6b</td>
<td>data 7b</td>
<td>data 8b</td>
<td>data 9b</td>
<td>data 10b</td>
</tr>
</tbody>
</table>