<div class="table-linearizable">
<table>
<caption>Artists! Albums! Years! Formats!</caption>
<thead>
<tr>
<th>Artist</th>
<th>Album</th>
<th class="numeric">Year</th>
<th class="numeric">Digital</th>
<th class="numeric">Vinyl</th>
</tr>
</thead>
<tbody>
<tr>
<td data-label="Artist"> Flaming Lips </td>
<td data-label="Album"> The Soft Bulletin </td>
<td data-label="Year" class="numeric"> 1999 </td>
<td data-label="Digital" class="numeric"> $9.99 </td>
<td data-label="Vinyl" class="numeric"> $22.99 </td>
</tr>
<tr>
<td data-label="Artist"> Nirvana </td>
<td data-label="Album"> Bleach </td>
<td data-label="Year" class="numeric"> 1991 </td>
<td data-label="Digital" class="numeric"> $8.99 </td>
<td data-label="Vinyl" class="numeric"> $20.99 </td>
</tr>
<tr>
<td data-label="Artist"> Leonard Cohen </td>
<td data-label="Album"> Old Ideas </td>
<td data-label="Year" class="numeric"> 2012 </td>
<td data-label="Digital" class="numeric"> $9.99 </td>
<td data-label="Vinyl" class="numeric"> $23.99 </td>
</tr>
<tr>
<td data-label="Artist"> Run the Jewels </td>
<td data-label="Album"> RTJ 4 🤜🏿 👈🏼 </td>
<td data-label="Year" class="numeric"> 2020 </td>
<td data-label="Digital" class="numeric"> $0.00 </td>
<td data-label="Vinyl" class="numeric"> $24.99 </td>
</tr>
</tbody>
</table>
</div>
<div
class="table-{{modifier}}"
{{#if tabindex}}tabindex="{{ tabindex }}"{{/if}}
{{#if role}}role="{{ role }}"{{/if}}
{{#if ariaLabelledBy}}aria-labelledby="{{ ariaLabelledBy }}"{{/if}}>
<table>
<caption {{#if captionId}}id="{{ captionId }}"{{/if}}>{{ caption }}</caption>
<thead>
<tr>
{{#each header}}
<th {{#if class}}class="{{ class }}" {{/if}}>{{ text }}</th>
{{/each}}
</tr>
</thead>
<tbody>
{{#each row}}
<tr>
{{#each col}}
<td
{{#if ../../dataLabels}}data-label="{{#with (lookup ../../header @index) }}{{text}}{{/with}}"{{/if}}
{{#if class}}class="{{ class }}" {{/if}}> {{ text }} </td>
{{/each}}
</tr>
{{/each}}
</tbody>
</table>
</div>
{
"caption": "Artists! Albums! Years! Formats!",
"header": [
{
"text": "Artist"
},
{
"text": "Album"
},
{
"text": "Year",
"class": "numeric"
},
{
"text": "Digital",
"class": "numeric"
},
{
"text": "Vinyl",
"class": "numeric"
}
],
"row": [
{
"col": [
{
"text": "Flaming Lips"
},
{
"text": "The Soft Bulletin"
},
{
"text": 1999,
"class": "numeric"
},
{
"text": "$9.99",
"class": "numeric"
},
{
"text": "$22.99",
"class": "numeric"
}
]
},
{
"col": [
{
"text": "Nirvana"
},
{
"text": "Bleach"
},
{
"text": 1991,
"class": "numeric"
},
{
"text": "$8.99",
"class": "numeric"
},
{
"text": "$20.99",
"class": "numeric"
}
]
},
{
"col": [
{
"text": "Leonard Cohen"
},
{
"text": "Old Ideas"
},
{
"text": 2012,
"class": "numeric"
},
{
"text": "$9.99",
"class": "numeric"
},
{
"text": "$23.99",
"class": "numeric"
}
]
},
{
"col": [
{
"text": "Run the Jewels"
},
{
"text": "RTJ 4 🤜🏿 👈🏼"
},
{
"text": 2020,
"class": "numeric"
},
{
"text": "$0.00",
"class": "numeric"
},
{
"text": "$24.99",
"class": "numeric"
}
]
}
],
"modifier": "linearizable",
"dataLabels": true
}
table {
width: 100%;
padding: 0;
margin: 1em 0;
font-size: .9em;
border-collapse: collapse;
border-spacing: 0;
border-collapse: collapse;
}
thead,
tbody,
tfoot {
width: 100%;
}
th, td {
font-family: $font-stack-sans;
vertical-align: top;
text-align: left;
border-bottom: solid 1px #ccc;
padding: $font-size-base/2 $font-size-base;
}
tr:nth-child(even) th,
tr:nth-child(even) td {
background: #f3f3f3;
}
th {
font-weight: bold;
}
caption {
color: #888;
caption-side: top;
text-align: left;
}
@media screen and (max-width: 37.5em) {
.table-linearizable {
thead {
display: none;
}
tr {
display: block;
padding: .4em;
margin: 0 0 1em;
border: solid 1px #ccc;
border-radius: .4em;
&:nth-child(even) td {
background: transparent;
}
}
td {
display: block;
padding: .6em;
border-bottom: dotted 1px #ccc;
text-align: right;
&:before {
content: attr(data-label);
float: left;
font-weight: bold;
}
&:last-child {
border: 0;
}
}
}
}
.table-scroll {
width: 100%;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
th.numeric,
td.numeric {
text-align: right;
}
Tables are one of the tougher elements to handle responsively. By default a table will not scale down well to smaller viewports.
Tables with few columns are good candidates for being linearized. On small viewports, each record is displayed as a card of heading/value pairs. This technique does require repeating each column header as a data attribute for each row.
For tables with many columns or a lot of data in each column, horizontal scrolling is probably the best option. The tab index is important to allow focus for keyboard users. Once focus is set on the table wrapper, the arrow keys can be used to scroll.
Table cells with .numeric
class will be right-aligned