响应式布局进阶篇:响应式表格

作者 | Brilliant Open Web团队

编辑 | Brilliant Open Web团队

本文继续在响应式布局上深入讨论,主要通过多个实际例子,探讨表格在不同设备下的响应式布局方式,以提供良好的用户体验。

当我们有大量结构化数据需要在页面上展现时,通常会使用表格。但如果表格的列超过一定数量,它们很有可能会溢出视口。在视口较窄的设备上,较宽的表格可能会强迫用户通过水平滚动才能浏览全部内容。有一些办法能优化这个问题,接下来我们会由易到难,介绍多种响应式表格的布局方式,分别是 隐藏表格列表格容器内滚动表格重组固定表格行列

固定列示意图

隐藏表格列

对于表格展现的数据来说,可能不是每一列都十分重要。我们可以通过媒体查询,在视口较窄的时候,隐藏表格里一些不太重要的信息。


@media screen and (max-width: 599px) {
.non-critical-col {
display: none;
}
}

隐藏表格列通过一个很直接的方式,使得表格能在窄视口设备上较好地展现。这样做最大的问题是,向用户隐藏了一部分结构化数据。如果用户确实需要获取这些数据,那他们别无选择,只能更换设备浏览了。所以,隐藏表格列需要谨慎,如果有可能,可以尝试使用缩写来展示数据。

表格容器内滚动

另一个比较简单的响应式表格实现是,把表格放在一个容器里,仅使该容器在水平方向可滚动。


<div class=“table-container”>
<table>

</table>
</div>


.table-container {
width: 100%;
overflow: auto;
}

仅使表格在容器滚动,可以避免页面出现水平滚动条,从而影响整个页面的浏览体验,同时也兼顾了表格数据展现的完整性。

表格重组

将表格的每一列转换为一行,可以将表格转换为普通的列表来展现。表格进行重组后,表头位于列表的最左边一列。我们可以通过媒体查询实现表格重组。

表格重组示意图


@media screen and (max-width: 599px) {
table {
border-spacing: 0;
}
table, tbody, tr, th, td {
display: block;
}
thead { /* 隐藏真实表头 */
display: none;
}
tr {
border-bottom: 1px solid #e0e0e0;
}
td {
position: relative;
height: 28px;
padding-left: 50%; /* 数据列左边留 50% 空间给新的表头 */
border-bottom: 1px solid #e0e0e0;
text-align: center;
background: #fff;
}
td::before {
content: attr(data-th); /* 使用 data-th 属性生成新的表头 */
position: absolute;
left: 25%;
transform: translateX(-50%); /* left 与 transform 配合实现表头居中 */
font-weight: 700;
}
}


<table>
<thead>
<tr>
<th>Name</th>
<th>1st</th>
<th>2nd</th>
<th>3rd</th>
<th>4th</th>
<th>5th</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td data-th=“Name”>Alice</td>
<td data-th=“1st”>0</td>
<td data-th=“2nd”>0</td>
<td data-th=“3rd”>1</td>
<td data-th=“4th”>0</td>
<td data-th=“5th”>4</td>
<td data-th=“Final”>5</td>
</tr>
<tr>
<td data-th=“Name”>Bob</td>
<td data-th=“1st”>0</td>
<td data-th=“2nd”>2</td>
<td data-th=“3rd”>0</td>
<td data-th=“4th”>4</td>
<td data-th=“5th”>0</td>
<td data-th=“Final”>6</td>
</tr>
</tbody>
</table>

表格重组的好处是,所有数据在视口内都是可展现的,不需要用户进行水平滚动。但这破坏了表格的原始组织形式,用户可能会感觉到数据展示不够直观。

固定表格行列

通过 position: sticky 可以使表格的行列固定,从而这些行列不会在滚动时移出视口。如下面的例子中,固定了表格的第一列和最后一列,其他列可以通过水平滚动来浏览。

表格列固定示意图


.table-container {
width: 100%;
overflow: auto; /* 使表格在容器内滚动 */
}
.table {
/* 表格共有七列,视口内始终展示五列 */
/* 包括头尾固定的两列以及中间三列,每列占 20vw 宽度 */
width: 140vw;
border-spacing: 0;
}
.table tr {
height: 56px;
}
.table th,
.table td {
width: 20vw; /* 表格每列的宽度 */
border-bottom: 1px solid #e0e0e0;
text-align: center;
background: #fff;
}
.table-sticky {
position: sticky; /* 使表格列固定 */
z-index: 1;
}
.table-sticky:first-child {
left: 0; /* 表格第一列固定在最左边 */
border-right: 1px solid #e0e0e0;
}
.table-sticky:last-child {
right: 0; /* 表格最后一列固定在最右边 */
border-left: 1px solid #e0e0e0;
}


<div class=“table-container”>
<table class=“table”>
<thead>
<tr>
<th class=“table-sticky”>Name</th>
<th>1st</th>
<th>2nd</th>
<th>3rd</th>
<th>4th</th>
<th>5th</th>
<th class=“table-sticky”>Final</th>
</tr>
</thead>
<tbody>
<tr>
<td class=“table-sticky”>Alice</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>4</td>
<td class=“table-sticky”>5</td>
</tr>
<tr>
<td class=“table-sticky”>Bob</td>
<td>0</td>
<td>2</td>
<td>0</td>
<td>4</td>
<td>0</td>
<td class=“table-sticky”>6</td>
</tr>
</tbody>
</table>

</div>

固定表格行列是一种比较优雅的解决方案,既能按照数据列的重要性展示内容,又不会造成数据缺失。在这种情况下,少量的水平滚动应该可以接受。

总结

本文首先介绍了表格在移动端下遇到的问题,随后通过四种方式,详细介绍了编写响应式表格的一些技巧。开发者可以根据实际情况,利用其中几种方式,优化不同尺寸设备呈现的表格内容,为用户提供更好的体验。但我们也可以发现,无论是哪种响应式表格,在移动端下都有一定的局限性。如果使用图表代替表格,或许会得到更好的数据展现效果。

本文内容主要来自开源书籍 《PWA 应用实战》 。该书由百度 Web 生态团队撰写与分享,记录了团队过去两年积累的 PWA 方面的经验,欢迎对 Web 和 PWA 有浓厚兴趣的读者加入我们,一起来维护这本书。

Brilliant Open Web 

BOW(Brilliant Open Web)团队,是一个专门的Web技术建设小组,致力于推动 Open Web 技术的发展,让Web重新成为开发者的首选。

BOW 关注前端,关注Web;剖析技术、分享实践;谈谈学习,也聊聊管理。

关注 OpenWeb开发者,让我们一起推动 OpenWeb技术的发展!

OpenWeb开发者

ID:BrilliantOpenWeb

技术连接世界,开放赢得未来