响应式数据表格

Avatar of Chris Coyier
Chris Coyier 发表

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

除了以下技术外,请参阅此汇总,其中包含对此问题的其他探讨。

Garrett Dimon

数据表格在响应式设计中表现不佳。就是这样。

他说的很有道理。数据表格可能非常宽,而且必须如此。为了使数据表格在表格中具有任何意义,需要将单行数据保持在一起。表格可以在宽度上伸缩,但它们只能缩小到一定程度,否则就会开始不舒服地换行单元格内容,或者根本无法缩小。

响应式设计完全是关于调整设计以适应不同尺寸的屏幕。那么,当屏幕比数据表格的最小宽度更窄时会发生什么?您可以缩小以查看整个表格,但文本大小会太小而无法阅读。或者,您可以放大到可读性点,但浏览表格将需要垂直和(悲伤的表情)水平滚动。

所以我们要做的是……

我们将使用“响应式设计”原则(CSS @media 查询)来检测屏幕是否小于表格的最大压缩程度。如果是,我们将重新格式化表格。

我们是优秀的开发者,并且在此处为我们的表格使用了纯语义标记。基本示例

<table>
	<thead>
	<tr>
		<th>First Name</th>
		<th>Last Name</th>
		<th>Job Title</th>
	</tr>
	</thead>
	<tbody>
	<tr>
		<td>James</td>
		<td>Matman</td>
		<td>Chief Sandwich Eater</td>
	</tr>
	<tr>
		<td>The</td>
		<td>Tick</td>
		<td>Crimefighter Sorta</td>
	</tr>
	</tbody>
</table>

我们的常规 CSS 没什么特别的

/* 
Generic Styling, for Desktops/Laptops 
*/
table { 
  width: 100%; 
  border-collapse: collapse; 
}
/* Zebra striping */
tr:nth-of-type(odd) { 
  background: #eee; 
}
th { 
  background: #333; 
  color: white; 
  font-weight: bold; 
}
td, th { 
  padding: 6px; 
  border: 1px solid #ccc; 
  text-align: left; 
}

现在开始使用小屏幕响应式内容。我们已经确定我们的最小表格宽度约为 760px,因此我们将设置我们的媒体查询,使其在窄于该宽度时生效。此外,我们将针对 iPad,因为它们正好位于该区域。

最大的变化是我们将强制表格不表现得像表格,方法是将每个与表格相关的元素设置为块级元素。然后通过保留我们最初添加的斑马条纹,它有点像每一行表格本身就成为一个表格,但宽度仅为屏幕宽度。不再需要水平滚动!然后对于每个“单元格”,我们将使用 CSS 生成的内容(:before)来应用标签,以便我们知道每个数据位的含义。

/* 
Max width before this PARTICULAR table gets nasty
This query will take effect for any screen smaller than 760px
and also iPads specifically.
*/
@media 
only screen and (max-width: 760px),
(min-device-width: 768px) and (max-device-width: 1024px)  {

	/* Force table to not be like tables anymore */
	table, thead, tbody, th, td, tr { 
		display: block; 
	}
	
	/* Hide table headers (but not display: none;, for accessibility) */
	thead tr { 
		position: absolute;
		top: -9999px;
		left: -9999px;
	}
	
	tr { border: 1px solid #ccc; }
	
	td { 
		/* Behave  like a "row" */
		border: none;
		border-bottom: 1px solid #eee; 
		position: relative;
		padding-left: 50%; 
	}
	
	td:before { 
		/* Now like a table header */
		position: absolute;
		/* Top/left values mimic padding */
		top: 6px;
		left: 6px;
		width: 45%; 
		padding-right: 10px; 
		white-space: nowrap;
	}
	
	/*
	Label the data
	*/
	td:nth-of-type(1):before { content: "First Name"; }
	td:nth-of-type(2):before { content: "Last Name"; }
	td:nth-of-type(3):before { content: "Job Title"; }
	td:nth-of-type(4):before { content: "Favorite Color"; }
	td:nth-of-type(5):before { content: "Wars of Trek?"; }
	td:nth-of-type(6):before { content: "Secret Alias"; }
	td:nth-of-type(7):before { content: "Date of Birth"; }
	td:nth-of-type(8):before { content: "Dream Vacation City"; }
	td:nth-of-type(9):before { content: "GPA"; }
	td:nth-of-type(10):before { content: "Arbitrary Data"; }
}

因此,桌面获得常规的表格体验,移动设备(或其他小屏幕)获得重新格式化且更易于浏览的表格

IE 怎么办?

IE 9 及以下版本不喜欢您将表格元素设置为display: block; 它会执行奇怪的操作并且无法正常工作。但 IE 9确实支持媒体查询。因此,到目前为止,我的解决方案只是将媒体查询样式包装在条件注释中。

<!--[if !IE]><!-->
<style>
   /* table-related media query stuff only */
</style>
/* Or an external stylesheet or whatever */
<!--<![endif]-->

如果问题仅仅是旧版本的 IE 不支持媒体查询,我们可以使用css3-mediaqueries-js项目(为所有媒体查询提供 polyfill 支持)或Respond(也是 polyfill,更小,但仅执行 min/max-width)。它们都运行良好。但这不是我们在此案例中的问题。

这在 IE 10 中运行良好,并且 IE 10 还会忽略条件注释,因此即使包装在 !IE 条件中,样式也会起作用。

查看

演示有两个页面,一个是响应式表格解决方案,另一个是到非响应式版本的链接,以便您可以来回切换以查看问题。

查看演示

在演示中,我使用了一些额外的媒体查询来强制移动设备的正文具有特定的宽度,以防止它们变得难以控制。查看源代码以获取。

这并不完美……

这只是针对小屏幕上的数据表格问题的一种潜在解决方案。它并不完美。可能存在一些可访问性问题(也可能没有,我对此真的不确定)。可能有一些花哨的 JavaScript 解决方案可以以不同的方式处理问题,并且也能很好地工作。如果出现此问题的其他解决方案,我将随时更新此页面。

更新:其他想法

Scott Jehl 提出了两个替代方案,它们都非常酷,并且与这个方案大不相同。这突出了一个重要点:选择哪种解决方案完全取决于数据表格的具体上下文。

其中一个根据图表中的数据创建饼图。在较窄的屏幕上,饼图显示,表格隐藏,否则仅显示信息更丰富的表格。可以说,移动版本更有用!

查看演示

下一个想法(Scott 认为是Todd Parker提出的)是在窄屏幕上将表格转换为表格的迷你图形,而不是显示整个表格。这向用户表明此处有一个要查看的数据表格,但不会过多地干扰内容。单击表格,转到仅查看表格的特殊屏幕,然后单击返回。

查看演示

移动优先版本由 Derek Pennycuff 创建。

版本以 div 开头,标签由伪元素和 Mobifreaks 的数据属性生成。

仅隐藏非必要内容版本由 Stewart Curry 创建

基于此 Gist实时演示)由 Hannes Kirsman 直接生成移动版本(无需 div 内容)。