Web 上的表格设计模式

已发表: 2022-03-10
快速总结↬表格是一种在行和列中显示大量数据的设计模式,并且似乎还没有失宠,所以让我们来看看我们如何在 2019 年在 Web 上创建表格。

表格是一种用于在行和列中显示大量数据的设计模式,使它们能够有效地对分类对象进行比较分析。 早在 2世纪,桌子就已用于此目的,当世界开始数字化时,桌子就与我们一起出现了。

Web 不可避免地会支持以表格格式显示数据。 HTML 表格以语义和结构适当的方式呈现表格数据。 但是,HTML 表格的默认样式并不是您见过的最美观的东西。 根据所需的视觉设计,需要在 CSS 前端做出一些努力来美化这些表格。 十年前,一篇关于“十大 CSS 表格设计”的文章发表在 Smashing Magazine 上,直到今天它仍然继续获得大量流量。

在过去的十年中,网络发生了很大的变化,让您的网站或应用程序适应它所查看的视口比以往任何时候都更加方便。话虽如此,我们必须继续做出考虑周全的设计选择,而不是妥协可访问性。 由于表格似乎不会很快失宠,让我们看看 2019 年如何在 Web 上创建表格。

跳跃后更多! 继续往下看↓

仅 CSS 选项

如果您的数据集不是那么大,并且不需要分页和排序等功能,那么请考虑使用无 JavaScript 选项。 您可以获得一些非常好的结果,这些结果在整个屏幕尺寸范围内都能很好地工作,而不会增加大型库的重量。

不幸的是,如果没有 JavaScript 在可访问性方面的一些 DOM 操作的帮助,我们只有少数 CSS-only 选项。 但对于小型数据集,它们通常就足够了。

选项 1:什么都不做

我们将从一个省力的场景开始。 如果您的数据适合只有几列和很多行的表,那么这样的表几乎可以开始移动。

在窄屏和宽屏上显示的少列多行的表格
在窄屏和宽屏上显示几列多行的表格(大预览)

您遇到的问题可能是在较宽的屏幕上空间太大,因此建议使用max-width “限制”表格的最大宽度,同时让它在窄屏幕上根据需要缩小。

请参阅 CodePen 上的 Pen Table #1: Few columns, many rows by (Chen Hui Jing)。

请参阅 CodePen 上的 Pen Table #1: Few columns, many rows by (Chen Hui Jing)。

如果您的数据本身不是文本行和文本行,则这种模式效果最好。 如果它们是数字或短语,你可能不用做太多就可以侥幸逃脱。

选项 2:设置卷轴样式

David Bushell 早在 2012 年就编写了他的响应式表格技术,其中涉及调用溢出并允许用户滚动查看更多数据。 有人可能会争辩说,这并不完全是一种响应式解决方案,但从技术上讲,容器正在响应视口的宽度。

以用户知道滚动上有更多数据的方式设置表格样式。
设置表格样式时,允许用户滚动查看更多数据。 (大预览)

让我们先看一下“基本”溢出。 想象一下我在基本周围使用空气引号,因为滚动阴影的样式绝不是。 尽管如此,在这种情况下,“基本”是指表格不会以任何方式转换的事实。

请参阅 CodePen 上 Chen Hui Jing 的 Pen Table #3: Style the scroll (basic)。

请参阅 CodePen 上 Chen Hui Jing 的 Pen Table #3: Style the scroll (basic)。

这种滚动阴影的技术来自于 Roma Komarov 和 Lea Verou,他们相互借鉴彼此的想法来创造魔法。 它依赖于使用多个渐变(线性和径向)作为包含元素上的背景图像,并使用background-attachment: local来相对于其内容定位背景。

这种技术的好处在于,对于不支持滚动阴影的浏览器,您仍然可以正常滚动表格。 它根本不会破坏布局。

另一个滚动选项是将表格标题从行配置翻转到列配置,同时将水平滚动应用于<tbody>元素的内容。 此技术利用 Flexbox 行为将表的行转换为列。

请参阅 CodePen 上 Chen Hui Jing 的 Pen Table #3: Style the scroll (flipped headers)。

请参阅 CodePen 上 Chen Hui Jing 的 Pen Table #3: Style the scroll (flipped headers)。

通过将display: flex应用于表格,它使<thead><tbody>都是 flex 子项,默认情况下它们在同一条 flex 行上彼此相邻。

我们还使<tbody>元素成为一个 flex 容器,从而使其中的所有<tr>元素也成为一个 flex 子元素,它们也布置在一个 flex 行中。 最后,每个表格单元格都必须将其显示设置为block而不是默认的table-cell

这种技术的优点是标题始终在视图中,就像固定的标题效果一样,因此用户在滚动数据列时不会丢失上下文。 需要注意的一点是,这种技术会导致视觉和源顺序的差异,这使得事情有点不直观。

撒上一些 JavaScript

如前所述,涉及通过修改display值来变形表格的布局选项有时会对可访问性产生负面影响,这需要一些小的 DOM 操作来纠正。

此外,Andrew Coyle 在设计数据表时提供了许多用户体验提示,包括分页、排序、过滤等功能(确实需要一些 JavaScript 才能启用的功能)。

如果您使用的是相对简单的数据集,也许您想为其中一些功能编写自己的函数。

行到块,具有可访问性修复

据我所知,这种响应式数据表技术源自 Chris Coyier 在 2011 年撰写的 CSS-Tricks 文章“响应式数据表”。此后,许多其他人对其进行了改编和扩展。

这种技术的要点是利用媒体查询来切换表格元素及其子元素的显示属性,以block在狭窄的视口上。

表格行成为狭窄视口上的单独堆叠块
将行折叠成块(大预览)

在狭窄的屏幕上,表格标题在视觉上是隐藏的,但仍存在于可访问性树中。 通过将数据属性应用于表格单元格,我们可以通过 CSS 显示数据的标签,同时将标签的内容保留在 HTML 中。 有关标记和样式的外观,请参阅下面的 CodePen:

请参阅 CodePen 上 Chen Hui Jing 的 Pen Table #2: Rows to blocks。

请参阅 CodePen 上 Chen Hui Jing 的 Pen Table #2: Rows to blocks。

原始方法在显示标签文本的伪元素上应用宽度,但这意味着您需要知道标签开始所需的空间量。 上面的示例使用了一种稍微不同的方法,标签和数据分别位于其包含块的相对两侧。

我们可以通过 flex 格式化上下文中的自动边距来实现这样的效果。 如果我们将每个<td>元素的 display 属性设置为 flex,因为伪元素会生成盒子,就好像它们是其原始元素的直接子元素一样,它们将成为<td>的 flex 子元素。

之后,在伪元素上设置margin-right: auto以将单元格的内容推送到单元格的远端边缘。

另一种进行窄视口布局的方法是使用 Grid 和display: contents的组合。 请注意,支持浏览器中的display: contents目前存在可访问性问题,在修复这些错误之前,不应在生产中使用此方法。

但也许您在解决这些错误后正在阅读本文,在这种情况下,这里有一个替代布局选项。

请参阅 CodePen 上 Chen Hui Jing 的 Pen Table #2: Rows to blocks (alt)。

请参阅 CodePen 上 Chen Hui Jing 的 Pen Table #2: Rows to blocks (alt)。

每个<tr>元素都设置为display: grid ,每个<td>元素都设置为display: contents 。 只有网格容器的直接子级参与网格格式化上下文; 在这种情况下,它是<td>元素。

display: contents应用于<td>时,它会被其内容“替换”,在这种情况下, <td>中的伪元素和<span>会变成网格子元素。

我喜欢这种方法的地方在于能够使用max-content来调整伪元素列的大小,确保该列始终是最长标签的宽度,而无需我们手动为其分配宽度值。

将来,当min-contentmax-contentfit-content的尺寸值(由 CSS Intrinsic & Extrinsic Sizing Module Level 3 涵盖)被支持为通用widthheight值时,我们将有更多的布局选项东西出来。

这种方法的缺点是您确实需要在表格单元格中的内容周围添加额外的<span><p> (如果它还没有的话),否则,将无法对其应用样式。

简单分页

这个例子展示了一个基本的分页实现,它是由 Gjore Milevski 在这个 CodePen 上修改的,用于对表行而不是 div 进行分页。 它是上一节中讨论的“样式滚动”示例的扩展。

请参阅 CodePen 上的 Pen Table #4: Simple pagination by Chen Hui Jing。

请参阅 CodePen 上的 Pen Table #4: Simple pagination by Chen Hui Jing。

从布局的角度来看,Flexbox 非常方便地将分页元素定位到各种视口大小。 不同的项目设计会有不同的要求,但 Flexbox 的多功能性应该可以让您相应地满足这些差异。

在这种情况下,分页以页面为中心并位于表格上方。 在较宽的屏幕上,用于向后和向前导航的控件位于页面指示器的两侧,但在窄屏幕上,所有四个都显示在页面指示器的上方。

我们可以通过利用order属性来做到这一点。 内容的视觉重新排序应始终考虑在内,因为此属性不会更改源顺序 - 只会更改它在屏幕上的显示方式。

简单排序

这个例子展示了一个基本的排序实现,由 Peter Noble 修改了这个代码片段,以适应文本和数字:

请参阅 Pen #Table 5:Chen Hui Jing 在 CodePen 上的简单排序。

请参阅 Pen #Table 5:Chen Hui Jing 在 CodePen 上的简单排序。

有某种指示符来指示当前正在对哪一列进行排序以及按什么顺序排序会很有用。 我们可以通过添加 CSS 类来做到这一点,然后可以根据需要设置样式。 在这种情况下,指标符号是在单击目标标题时切换的伪元素。

简单搜索

这个例子是一个基本的过滤功能,它遍历每个表格单元格的所有文本内容,并应用一个 CSS 类来隐藏所有与搜索输入字段不匹配的行。

请参阅 CodePen 上的 Pen Table #6: Simple filtering by Chen Hui Jing。

请参阅 CodePen 上的 Pen Table #6: Simple filtering by Chen Hui Jing。

这样的实现相对幼稚,如果您的用例需要它,那么按列搜索可能是有意义的。 在这种情况下,将每个输入字段作为各自列中表的一部分可能是一个好主意。

让图书馆处理它

上面的 JavaScript 片段用于演示如何增强具有大量数据的表,以使这些表的用户更轻松。 但是对于非常大的数据集,使用现有的库来管理大型表可能很有意义。

列切换模式是一种将非必要列隐藏在较小屏幕上的模式。 通常,我不喜欢仅仅因为视口狭窄就隐藏内容,但是 Filament Group 的 Maggie Costello Wachs 的这种方法通过提供一个下拉菜单来解决我的疑虑,该菜单允许用户将隐藏的列切换回看法。

上述文章发表于 2011 年,但 Filament Group 此后开发了一整套称为 Tablesaw 的响应式表格插件,其中包括排序、行选择、国际化等功能。

TableSaw 中的列切换功能也不再依赖于 jQuery,这与原始文章中的示例不同。 Tablesaw 是目前我能找到的唯一一个不依赖 jQuery 的库之一。

包起来

有无数的表格设计模式,您选择哪种方法在很大程度上取决于您拥有的数据类型和该数据的目标受众。 归根结底,表格是一种组织和呈现数据的方法。 重要的是要弄清楚哪些信息对您的用户最重要,并决定最能满足他们需求的方法。

延伸阅读

  • “仅 CSS 响应式表”,David Bushell
  • “可访问、简单、响应式的表格”,CSS-Tricks 的 Davide Rizzo
  • “响应式表格布局,”马特·史密斯
  • “响应式模式:表格”,布拉德·弗罗斯特
  • “嘿,使用桌子还是可以的,”阿德里安·罗塞利
  • “表格、CSS 显示属性和 ARIA,”Adrian Roselli
  • “数据表”,海登·皮克林