使用表格来组织数据

LESSON 9 · 2014/03/19

英文原文:organizing-data-tables

最初HTML问世的时候表格无处不在,是网站建设的主要方式。它们被用来定位内容以及构建一个页面的整体布局。幸亏我们已经走过了这段蛮长的道路,现在表格是、应该、只用于组织数据

当处理大量的表格式数据的时候,表格是其显示的基础。使用表格可以让数据更加的容易阅读和消化,让用户对数据能有个全局的理解。

表格用于数据展示而不是页面设计的转变仍然有些挑战。在HTML中表格如何被构建这在很大程度上取决于数据以及这些数据如何展示。除了在HTML中的标记之外,表格还需要使用CSS来对其施加样式,以此来让样式变得更加直观易懂。

创建表格

一般来说表格是由行和列构成的,这些行和列相互交叉。在HTML中,需要几个元素来创建一个表格,至少需要tabletrtd元素,更进一步的话,还需要th元素,将这些元素组合则可创建一个完整的表格。

表格

在页面中初始化一个表格需要使用table元素,使用table元素表示其内的数据将会显示在两个或者更多的维度。table元素只是用来初始化,还需要在内随着内容包裹表格行。

<table>
  ...
</table>

表格行

在HTML中定义了表格之后,使用tr元素增加表格的行。一个表格可以包含很多个表格行(tr元素),根据数据的数量,表格行可以变得很高。表格行内的数据则使用td元素添加,使用th元素添加表头。

<table>
  <tr>
    ...
  </tr>
  <tr>
    ...
  </tr>
</table>

表格数据

在表格中添加数据的最好方法便是使用td元素。td元素创建了个一个单元格。表格行内td元素的数量也就是表格列的数量。当然如果单元格内内容是表头内容则应该使用th元素而不是td元素。

<table>
  <tr>
    <td>Date</td>
    <td>Opponent</td>
    <td>Location</td>
    <td>Time</td>
  </tr>
  <tr>
    <td>Monday, March 5th</td>
    <td>Indiana Pacers</td>
    <td>United Center, Chicago, IL</td>
    <td>7:00 PM</td>
  </tr>
  <tr>
    <td>Wednesday, March 7th</td>
    <td>Milwaukee Bucks</td>
    <td>Bradley Center, Milwaukee, WI</td>
    <td>7:00 PM</td>
  </tr>
  <tr>
    <td>Thursday, March 8th</td>
    <td>Orlando Magic</td>
    <td>United Center, Chicago, IL</td>
    <td>7:00 PM</td>
  </tr>
  <tr>
    <td>Saturday, March 10th</td>
    <td>Utah Jazz</td>
    <td>United Center, Chicago, IL</td>
    <td>7:00 PM</td>
  </tr>
</table>

表格数据

Date Opponent Location Time
Monday, March 5th Indiana Pacers United Center, Chicago, IL 7:00 PM
Wednesday, March 7th Milwaukee Bucks Bradley Center, Milwaukee, WI 7:00 PM
Thursday, March 8th Orlando Magic United Center, Chicago, IL 7:00 PM
Saturday, March 10th Utah Jazz United Center, Chicago, IL 7:00 PM

表头

th元素用于指定表格的表头。表头元素的工作方式很像是单元格,而使用表头的意义在于表头为表格提供了语义化的意义,表明了其内的数据是标题。这样就和标题元素h1之与段落元素p一样,只是标题元素可以置于段落标签之内,而表头不能这样做。使用标题标签还可以提供更简单的办法来对标题施加样式,对于表头也是如此。

表格的行和列都可以有表头,scope属性专门用来指定该表头是属于行还是列的,scope属性的值rowcolrowgroupcolgroup中最常用的rowcol分别表示了属于行和列的表头。

headers属性

headers属性和scope属性非常相似。默认情况下scope属性只用于th元素之上。而如过一个单元格,无论是th还是td需要和另外一个表头关联就需要使用headers属性。th或者td元素中headers属性的值需要和所关联单元格的id相匹配。

另外,默认情况下表头回事粗体和居中。如果需要可以使用CSS样式覆盖。

<table>
  <tr>
    <th scope="col">Date</th>
    <th scope="col">Opponent</th>
    <th scope="col">Location</th>
    <th scope="col">Time</th>
  </tr>
  <tr>
    <td>Monday, March 5th</td>
    <td>Indiana Pacers</td>
    <td>United Center, Chicago, IL</td>
    <td>7:00 PM</td>
  </tr>
  <tr>
    <td>Wednesday, March 7th</td>
    <td>Milwaukee Bucks</td>
    <td>Bradley Center, Milwaukee, WI</td>
    <td>7:00 PM</td>
  </tr>
  <tr>
    <td>Thursday, March 8th</td>
    <td>Orlando Magic</td>
    <td>United Center, Chicago, IL</td>
    <td>7:00 PM</td>
  </tr>
  <tr>
    <td>Saturday, March 10th</td>
    <td>Utah Jazz</td>
    <td>United Center, Chicago, IL</td>
    <td>7:00 PM</td>
  </tr>
</table>

表头Demo

Date Opponent Location Time
Monday, March 5th Indiana Pacers United Center, Chicago, IL 7:00 PM
Wednesday, March 7th Milwaukee Bucks Bradley Center, Milwaukee, WI 7:00 PM
Thursday, March 8th Orlando Magic United Center, Chicago, IL 7:00 PM
Saturday, March 10th Utah Jazz United Center, Chicago, IL 7:00 PM

合并单元格

有时候两个或者多个单元格需要合并成一个单元格,或许是因为相邻的单元格内容一样,也或许是处于样式的考虑。在此我们可以使用colspanrowspan属性,这两个熟悉可以用到表格数据或者表头上。

colspan属性用于需要跨列合并的单元格,rowspan则用于需要跨行合并的单元格。两者都只接受整数的值,表示跨的单元格格数,1是默认的值。

<table>
  <tr>
    <th scope="col">Date</th>
    <th scope="col">Opponent</th>
    <th scope="col">Location</th>
    <th scope="col">Time</th>
  </tr>
  <tr>
    <td>Monday, March 5th</td>
    <td>Indiana Pacers</td>
    <td>United Center, Chicago, IL</td>
    <td rowspan="4">7:00 PM</td>
  </tr>
  <tr>
    <td>Wednesday, March 7th</td>
    <td colspan="2">Milwaukee Bucks, Bradley Center, Milwaukee, WI</td>
  </tr>
  <tr>
    <td>Thursday, March 8th</td>
    <td>Orlando Magic</td>
    <td rowspan="2">United Center, Chicago, IL</td>
  </tr>
  <tr>
    <td>Saturday, March 10th</td>
    <td>Utah Jazz</td>
  </tr>
</table>

合并单元格Demo

Date Opponent Location Time
Monday, March 5th Indiana Pacers United Center, Chicago, IL 7:00 PM
Wednesday, March 7th Milwaukee Bucks, Bradley Center, Milwaukee, WI
Thursday, March 8th Orlando Magic United Center, Chicago, IL
Saturday, March 10th Utah Jazz

表格结构

知道如何创建一个表格以及安排数据是一个非常强大的,也是每个前端工程师都需要掌握的技能。除了上述的表格构建要点之外,还有其他的元素来帮助在表格中组织数据,这些元素包括captiontheadtfoot以及tbody

表格标题

使用caption元素来为表格提供说明或者标题。表格标题让用户明白表格所包含的东西。caption需要紧跟在table标签之后。它的位置默认在表格的顶部,当然也可以使用CSS来改变。如果表格在figure元素之内,那么就需要用figcaption元素替换caption元素。

<table>
  <caption>Chicago Bulls Schedule - Week of March 5th</caption>
  ...
</table>

表格标题Demo

Chicago Bulls Schedule - Week of March 5th
Date Opponent Location Time
Monday, March 5th Indiana Pacers United Center, Chicago, IL 7:00 PM
Wednesday, March 7th Milwaukee Bucks Bradley Center, Milwaukee, WI 7:00 PM
Thursday, March 8th Orlando Magic United Center, Chicago, IL 7:00 PM
Saturday, March 10th Utah Jazz United Center, Chicago, IL 7:00 PM

表格theadtbodytfoot元素

一个表格可以使用theadtbodytfoot这三个元素来分成对应的三个部分,这样可以更好的组织数据。

thead包裹了表头元素,表示属于表格的头部,thead应该在caption元素和tbody之间。

紧跟着thead之后可以是tbody元素或者tfoot元素。之前tfoot元素需要紧跟在thead之后,这点在HTML5中已经被取消。现在只要有唯一的父元素,它们的顺序随意。而且,tbody元素需要包含表格中最重要的内容,tfoot元素则包含表格概述性的内容。

<table>
  <caption>...</caption>
  <thead>
    ...
  </thead>
  <tbody>
    ...
  </tbody>
  <tfoot>
    ...
  </tfoot>
</table>

表格边框

表格中的一个能够让数据更加易懂的设计组件便是边框。表格,行,列,或者独立单元格的边框可以对表格数据的理解和表格的快速浏览有着很大的影响。在CSS中定义边框样式的时候在此由两个属性需要使用border-collapseborder-spacing

border-collapse属性

表格由外面的table元素和td元素组成,同时对两者使用边框会使得边框叠加。譬如,在整个表格使用2px的边框,然后在单元格上再使用2px的边框,最终会使得边框便是4px。

border-collapse属性定义了表格边框的模式。border-collapse属性由三个值,包括:collapseseparateinherit。默认值separate表示不同的边框会叠加起来,而collapse则表示不同的边框会合并起来,选用单元格作为主要的边框。

table {
  border: 2px solid blue;
  border-collapse: separate;
}
th, td {
  border: 2px solid red;
}

border-collapse属性Demo

Luke Brad
88 76

separate

Luke Brad
88 76

collapse

border-spacing属性

border-collapse属性的separate值让表格的边框不重叠,而border-spacing属性则决定了两个边框的空间大小,在上述的例子中,如果再设置border-spacing属性为2px,那么也就创建了一个总共6px的边框。

table {
  border: 2px solid blue;
  border-collapse: separate;
  border-spacing: 2px;
}
th, td {
  border: 2px solid red;
}

border-spacing属性Demo

Luke Brad
88 76

添加边框

为整个表格增加边框确实挺简单的,但是为行或者单元格增加边框就有点难度。下面是几个添加边框的例子,在此额外推荐的例子是来自Twitter的tables within Bootstrap

行边框

为表格的行与行之间添加边框,可以通过为单元格添加底部的边框来实现,去除最后一行的边框只需使用伪类last-child来实现。

table {
  border-collapse: collapse;
  border-spacing: 0;
}
th, td {
  border-bottom: 1px solid #c6c9cc;
}
tr:last-child td {
  border: 0;
}
行边框Demo
Track Artist Length
We Are Young Fun. 4:10
Pumped Up Kicks Foster the People 3:59
Midnight City M83 4:03

单元格边框

为单元格添加边框也很简单,只需为每一个单元格添加即可,只是还需要设置表格的边框为重叠。

table {
  border-collapse: collapse;
  border-spacing: 0;
}
th, td {
  border: 1px solid #c6c9cc;
}
单元格边框Demo
Track Artist Length
We Are Young Fun. 4:10
Pumped Up Kicks Foster the People 3:59
Midnight City M83 4:03

文本的对齐

除了表格边框之外,单元格内容,横向或者纵向的垂直对于表格格式也很重要。一般来说,名字,描述左对齐,数字或者金额右对齐,其他类型的内容,根据上下文来对齐,一般来说是居中。横向对齐可以使用CSS中的text-align属性,这点在排版一章讲过。

垂直对齐可以使用vertical-align属性,vertical-align属性仅仅在display属性为inlinetable-cell的元素中起作用。在边个内,最常用的便是topmiddlebottom

HTML

<table>
  <thead>
    <tr>
      <th colspan="2">Items</th>
      <th class="qty">Qty</th>
      <th class="price">Price</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="item">Envisioning Information <span>By Edward R. Tufte – Hardcover</span></td>
      <td class="stock in">In Stock</td>
      <td class="qty">1</td>
      <td class="price">$33.32</td>
    </tr>
    <tr>
      <td class="item">Outliers <span>By Malcolm Gladwell – Hardcover</span></td>
      <td class="stock in">In Stock</td>
      <td class="qty">2</td>
      <td class="price">$33.58 <span>($16.79 × 2)</span></td>
    </tr>
    <tr>
      <td class="item">Don’t Make Me Think <span>By Steve Krug – Paperback</span></td>
      <td class="stock out">Out of Stock</td>
      <td class="qty">1</td>
      <td class="price">$22.80</td>
    </tr>
    <tr>
      <td class="item">Steve Jobs <span>By Walter Isaacson – Hardcover</span></td>
      <td class="stock in">In Stock</td>
      <td class="qty">1</td>
      <td class="price">$17.49</td>
    </tr>
  </tbody>
  <tfoot>
    <tr class="sub">
      <td colspan="3">Subtotal</td>
      <td>$107.19</td>
    </tr>
    <tr class="tax">
      <td colspan="3">Tax</td>
      <td>$10.71</td>
    </tr>
    <tr class="total">
      <td colspan="3">Total</td>
      <td>$117.90</td>
    </tr>
  </tfoot>
</table>

CSS

table {
  border-collapse: collapse;
  border-spacing: 0;
}
th, td {
  border: 1px solid #c6c9cc;
  vertical-align: top;
}
th {
  font-size: 11px;
  text-transform: uppercase;
}
th.qty, th.price {
  text-align: center;
}
tbody td.item {
  color: #404853;
  font-weight: bold;
}
tbody td.stock, tbody td.qty, tbody td.price {
  vertical-align: middle;
}
tbody td.stock, tbody td.qty {
  text-align: center;
}
tbody td.price {
  text-align: right;
}
tfoot td {
  text-align: right;
}
tfoot tr.sub td, tfoot tr.tax td {
  color: #8c8c8c;
  font-size: 12px;
}
tfoot tr.total td {
  color: #404853;
  font-size: 14px;
  font-weight: bold;
}
.in {
  color: #00b515;
}
.out {
  color: #b50000;
}
span {
  color: #8c8c8c;
  display: block;
  font-size: 12px;
  font-weight: normal;
}

文本对齐Demo

Items Qty Price
Envisioning Information By Edward R. Tufte – Hardcover In Stock 1 $33.32
Outliers By Malcolm Gladwell – Hardcover In Stock 2 $33.58 ($16.79 × 2)
Don’t Make Me Think By Steve Krug – Paperback Out of Stock 1 $22.80
Steve Jobs By Walter Isaacson – Hardcover In Stock 1 $17.49
Subtotal $107.19
Tax $10.71
Total $117.90

表格条纹(Table Striping)

为了增加表格的易读性,通过设置相邻行不同的背景颜色来创建出表格的“条纹”,这样使得表格更加的易于辨认,更加易于浏览。其中一个方案是设置不同的类名,另一个方案是使用nth-child伪类选择器,选择odd以及even行。

th {
  background: #404853;
  background: linear-gradient(#687587, #404853);
  color: #fff;
}
tbody tr:nth-child(even) td {
  background: #e8eae9;
  background: linear-gradient(#f7faf9, #e8eae9);
}
tfoot tr.total td {
  background: #e8eae9;
  background: linear-gradient(#f7faf9, #e8eae9);
}

表格条纹Demo

Items Qty Price
Envisioning Information By Edward R. Tufte – Hardcover In Stock 1 $33.32
Outliers By Malcolm Gladwell – Hardcover In Stock 2 $33.58 ($16.79 × 2)
Don’t Make Me Think By Steve Krug – Paperback Out of Stock 1 $22.80
Steve Jobs By Walter Isaacson – Hardcover In Stock 1 $17.49
Subtotal $107.19
Tax $10.71
Total $117.90