HTML Tables & CSS

Table Purpose

  • Structure of a Table
  • Caption
  • caption-side property
  • text-align and text-transform property
  • Borders & Spacing
  • border-collapse
  • border-spacing
  • Other Table Properties
  • empty-cells property
  • vertical-align
  • display property
  • columns
  • table-layout property
  • Exercise / solution
  • Static rows and colums
  • Accessibility
  • Mobile

Table Purpose

Presentation of Data

  • Presenting
  • Comparing
  • Sorting
  • Calculating
  • Cross Referencing

NOT for presentation

Structure of a Table

<table>
  <caption></caption>
  <colgroup>
    <col/>
  </colgroup>
  <thead>
    <tr>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td></td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <th></th>
    </tr>
  </tfoot>
</table>

Structure of a Table

<table>
  <caption>Table Caption</caption>
  <colgroup>
    <col/>
  </colgroup>
  <thead></thead>
  <tbody></tbody>
  <tfoot></tfoot>
</table>

Captions

Caption

  • Specifies the title of table
  • Always the first child of a <table>
  • Can be positioned on top or bottom with caption-side
  • In FF, can be top, bottom, left or right of table
  • Can be styled
  • CSS: Inherits from table

caption-side property

caption-side property

Put on the <table>, not the <caption>.

supported

caption-side: top; 
caption-side: bottom;

Experimental

caption-side: left; 
caption-side: right; 
caption-side: top-outside; 
caption-side: bottom-outside;

In the specification

caption-side: inline-start;
caption-side: inline-end;

deprecated:

<table align="left | top | right | bottom">

caption-side property

<caption> styling

<caption> notes

caption-side: bottom; text-align: right; can look good on short tables: similar to a figure caption.

text-align and text-transform property

text-transform property

text-transform: capitalize;
capitalize | uppercase | lowercase | none | full-width | full-size-kana;
  • Takes into account language-specific case mapping rules
  • First unicode letter or number. Initial punctuations of words are ignored
  • uppercase can be hard to read.

text-align & text-transform

Borders & Spacing

border-collapse

border-collapse: separate | collapse | inherit

When the borders are collapsed border-spacing is irrelevant. When separate, it matters!

border-spacing property

border-spacing: <length> <length>?;

The look you want is probably:

table, td, th {border: none;}
table {border-spacing: 5px 10px;}
  • one length: vertical and horizontal padding are the same.
  • two lengths: first is horizontal, second is vertical
  • Note: not TRouBLe
  • Irrelevant if border-collapse: collapse
  • Empty space is part of the table, not the column, tbody, row or cell.

table spacing to improve legibility

Other Table Properties

empty-cells property

empty-cells: show | hide

Similar to:

td:empty, th:empty {
  visibility: collapse;
  }
  • ignored if border-collapse: separate
  • applies to elements with diplay of table-cell
  • property of table or the cells themselves

empty-cells

vertical-align property

vertical-align: baseline | top | bottom | middle |
sub | super | text-top | text-bottom | <percentage> | <length>

applied to thead, tfoot, tbody, tr, td, th, but not table.

  • baseline: Aligns the baseline of the cell with the baseline of all other cells in the row that are baseline-aligned.
  • top: Aligns the top padding edge of the cell with the top of the row.
  • middle: Centers the padding box of the cell within the row.
  • bottom: Aligns the bottom padding edge of the cell with the bottom of the row.
  • sub, super, text-top, text-bottom, <length>, and <percentage> equal baseline

vertical-align

All the display properties

<display-outside> values

display: block;
display: inline;
display: run-in;

<display-inside> values

display: flow;
display: flow-root;
display: table;
display: flex;
display: grid;
display: ruby;

<display-outside> plus <display-inside> values

display: block flow;
display: inline table;
display: flex run-in;

<display-listitem> values

display: list-item;
display: list-item block;
display: list-item inline;
display: list-item flow;
display: list-item flow-root;
display: list-item block flow;
display: list-item block flow-root;
display: flow list-item block;

<display-internal> values

display: table-row-group;
display: table-header-group;
display: table-footer-group;
display: table-row;
display: table-cell;
display: table-column-group;
display: table-column;
display: table-caption;
display: ruby-base;
display: ruby-text;
display: ruby-base-container;
display: ruby-text-container;

<display-box> values

display: contents;
display: none;

<display-legacy> values

display: inline-block;
display: inline-table;
display: inline-flex;
display: inline-grid;

global values

display: inherit;
display: initial;
display: unset;
display: revert;

display property

display: table | table-cell
display: table;
display: table-row-group;
display: table-header-group;
display: table-footer-group;
display: table-row;
display: table-cell;
display: table-column-group;
display: table-column;
display: table-caption;
.parent {
  display: table;
}
.child {
  display: table-cell;
  vertical-align: baseline;
}

Related display values

table-row-group
Behaves like the <tbody> element.
table-header-group
Behaves like the <thead> element.
table-footer-group
Behaves like the <tfoot> element.
table-row
Behaves like the <tr> element.
table-cell
Behaves like the <td> element.
table-column-group
Behaves like the <colgroup> element.
table-column
Behaves like the <col> element.
table-caption
Behaves like the <caption> element.

columns

<col> Syntax

<table>
  <caption>u.s. women's national team</caption>
<colgroup>
  <col class="name"/>
  <col class="number"/>
  <col class="position"/>
  <col class="games"/>
  <col class="goals"/>
  <col class="assists"/>
  </colgroup>
<thead>....

<col> Styling

limited stylability

border: /* if table { border-collapse: collapse;} is set */
background:
width:
visibility: /* collapse value only */

styling columns

table-layout property

table-layout: auto | fixed
  • auto - widths of table and cells fit content.
  • fixed - widths of table and columns set by <col> width or first row of cells. (with too-wide cells observing overflow value.
  • fixed renders faster - only need first row downloaded to start painting.

table-layout property

Exercise

Style the USNWT table for legibility

display:
caption-side:
border-collapse:
border-spacing:
empty-cells:
table-layout:
vertical-align:
text-align:
table
colgroup
colspan
thead
tbody
tfoot
tr
th
td
table, td, th {}
table {}
col.name {}
col.number {}
col.position {}
col.games {}
col.goals {}
col.assists {}
caption {}
thead {}
tbody {}

Open in browser

Intentionally left blank

No cheating!

Solution

Static Top Row

Static Left Column

Static header, footer & left column

Accessibility

  • Use proportional rather than absolute sizing
  • display: other than table removes the table semantics
  • if you do convert to grid, use aria-roles.
  • If table maintains selection state, has two-dimensional navigation, or allows cell rearrangement use grid or treegrid roles instead.

On Mobile

  • Scroll
  • Fix header and left column, enabling scrolling
  • Linearize
  • hide some columns / allow user selection
  • Shrink (col.club { visibility: collapse; })

Grid

Next ➹

Links