使用 <a> 元素而不是 <tr> 来获取可点击的行
Using <a> element instead of <tr> to get clickable rows
我想在 html table 中创建可点击的行。每行应该是 link 导致不同的页面。我当然可以添加 onclick
处理程序,但这会产生一种糟糕的 UI - 可访问性差,没有键盘导航,没有 right/middle 单击...
我找到了更好的方法。不是使用普通的 table
元素,而是通过 css display
规则强制 div
s 充当不同的 table 标签。对于行,使用 a
-s 和适当的 href 属性。
我的意思是:
.table {
display: table;
border-collapse: collapse;
font-family: sans-serif;
width: 100%;
}
.thead {
display: table-header-group;
}
.tbody {
display: table-row-group;
}
.td, .th {
display: table-cell;
padding: 5px 10px;
text-align: center;
}
.tr {
display: table-row;
}
.thead > .tr {
background: #ccc;
color: #555;
}
a.tr {
text-decoration: none;
color: black;
}
a.tr:hover {
background: #eee;
cursor: pointer;
}
<div class="table">
<div class="thead">
<div class="tr">
<div class="th">ID</div>
<div class="th">Name</div>
</div>
</div>
<div class="tbody">
<a class="tr" href="524.html">
<div class="td">524</div>
<div class="td">John Smith</div>
</a>
<a class="tr" href="331.html">
<div class="td">331</div>
<div class="td">Miles Corner</div>
</a>
</div>
</div>
请注意行是如何可点击的,您可以在它们之间切换,并且有一个很好的工具提示显示 link 您将前往。比onclick好多了。
如果我使用像 React 这样的框架,我什至不必用 div-s 替换所有元素。我可以只添加 <a>
标签而不是 <tr>
s 就可以了。
我的问题是,有什么收获?我错过了什么?是否存在某些可访问性、浏览器兼容性或其他不这样做的原因?
有一些问题,我建议使用另一种 UI 模式,它更易于访问且用途更广:
使用带有主键(或对用户最重要的信息)的单元格,在其文本周围放置 <a>
。在您的情况下,这可能是 Name-column.
<td><a href="…">John Simth</a></td>
这不仅解决了您的可访问性问题,还解决了我们通常在 table 中考虑的其他设计注意事项。
- 为了便于访问,您的解决方案中没有公开任何 table 结构。这可以通过
aria-role
解决,但不推荐这样做,并且支持可能会有所不同。这种结构对于在 table 内部导航很重要,通常是通过方向键(网格导航)
- table 数据 TD 和 table headers TH 之间的关系未标记。这在您的示例中可能并不重要,因为名称很明显,但是随着数据的增加,它变得非常重要
- 任何交互式元素,如 links,都需要可聚焦。通过 Tab 键,您可以导航到它,然后使用 Space 或 Enter
激活它
- 这个重点需要在视觉上很明显(您可以添加
.tr:focus
class 并以不同的方式设置您的行的样式)
- 如果您向 table 行添加复选框,这些复选框也需要可聚焦。因此,通过提供 classic link,您将兼容。
- A classical table 行不提供让用户直观地点击它的功能可见性。 link 确实并且被广泛理解
我想在 html table 中创建可点击的行。每行应该是 link 导致不同的页面。我当然可以添加 onclick
处理程序,但这会产生一种糟糕的 UI - 可访问性差,没有键盘导航,没有 right/middle 单击...
我找到了更好的方法。不是使用普通的 table
元素,而是通过 css display
规则强制 div
s 充当不同的 table 标签。对于行,使用 a
-s 和适当的 href 属性。
我的意思是:
.table {
display: table;
border-collapse: collapse;
font-family: sans-serif;
width: 100%;
}
.thead {
display: table-header-group;
}
.tbody {
display: table-row-group;
}
.td, .th {
display: table-cell;
padding: 5px 10px;
text-align: center;
}
.tr {
display: table-row;
}
.thead > .tr {
background: #ccc;
color: #555;
}
a.tr {
text-decoration: none;
color: black;
}
a.tr:hover {
background: #eee;
cursor: pointer;
}
<div class="table">
<div class="thead">
<div class="tr">
<div class="th">ID</div>
<div class="th">Name</div>
</div>
</div>
<div class="tbody">
<a class="tr" href="524.html">
<div class="td">524</div>
<div class="td">John Smith</div>
</a>
<a class="tr" href="331.html">
<div class="td">331</div>
<div class="td">Miles Corner</div>
</a>
</div>
</div>
请注意行是如何可点击的,您可以在它们之间切换,并且有一个很好的工具提示显示 link 您将前往。比onclick好多了。
如果我使用像 React 这样的框架,我什至不必用 div-s 替换所有元素。我可以只添加 <a>
标签而不是 <tr>
s 就可以了。
我的问题是,有什么收获?我错过了什么?是否存在某些可访问性、浏览器兼容性或其他不这样做的原因?
有一些问题,我建议使用另一种 UI 模式,它更易于访问且用途更广:
使用带有主键(或对用户最重要的信息)的单元格,在其文本周围放置 <a>
。在您的情况下,这可能是 Name-column.
<td><a href="…">John Simth</a></td>
这不仅解决了您的可访问性问题,还解决了我们通常在 table 中考虑的其他设计注意事项。
- 为了便于访问,您的解决方案中没有公开任何 table 结构。这可以通过
aria-role
解决,但不推荐这样做,并且支持可能会有所不同。这种结构对于在 table 内部导航很重要,通常是通过方向键(网格导航) - table 数据 TD 和 table headers TH 之间的关系未标记。这在您的示例中可能并不重要,因为名称很明显,但是随着数据的增加,它变得非常重要
- 任何交互式元素,如 links,都需要可聚焦。通过 Tab 键,您可以导航到它,然后使用 Space 或 Enter 激活它
- 这个重点需要在视觉上很明显(您可以添加
.tr:focus
class 并以不同的方式设置您的行的样式) - 如果您向 table 行添加复选框,这些复选框也需要可聚焦。因此,通过提供 classic link,您将兼容。
- A classical table 行不提供让用户直观地点击它的功能可见性。 link 确实并且被广泛理解