Previously I have demonstrated a responsive strategy for tables. While those design patterns work, they do so only to a certain point, revealing their limitations as more table columns are added and the viewport is narrowed. To create fully adaptive solutions we often need to take a slightly counter-intuitive approach: writing the markup and presentation for mobile devices first, then using CSS to create an appropriate appearance on larger screens.
Examples of this approach include the browser compatibility tables featured in recent articles on content-fit and other new CSS properties on this blog. The structure of these “tables”, shown below, does not actually use table markup, but a definition list:
<p class="definition-table-caption">Browser support
<dl class="definition-table">
<dt data-version="Chrome 12+"><img src="chrome.svg" alt="Chrome">
<dd>Chrome 12+
<dt data-version="Firefox 14+"><img src="firefox.svg" alt="Firefox">
<dd>Safari 6+
<dt data-version="Android 4+"><img src="android.svg" alt="Android">
<dd>Android 4+
</dl>
In this case, <dt>
tags correspond to table header cells, and <dd>
elements to <td>
’s. Note that the content of each declaration is duplicated in the value of the data
attribute for its matching definition term. (The HTML5 attribute is free-form: any suffix after data-
is valid, and once created, the attribute may contain any value.)
Setting up the CSS
We’ll assume that the definition list defaults to the appearance of a horizontally-oriented table, with “table header” cells across the top. I will use display: table and related properties to achieve that:
p.definition-table-caption {
text-align: center;
font-weight: bolder;
}
dl.definition-table {
display: table;
}
dl.definition-table dt {
font-weight: bolder;
display: table-cell;
text-align: center;
}
dl.definition-table dt img {
margin: .5rem;
width: 3rem;
}
To create the look of a table out of a definition list, we’ll hide the actual declarations, and express the value of the data-version
attribute below each of the terms:
dl.definition-table dd {
display: none;
}
dl.definition-table dt:after {
display: block;
position: relative;
content: attr(data-version);
left: 0; top: 0;
}
This creates the appearance of a table, without using any actual table markup.
Making the table adaptive
As the browser window narrows, we want to re-orient the “table” structure, placing the information in horizontal rows. At an appropriate @media breakpoint we’ll turn back on the <dd>
tags, floating them to the right, while displaying the related term to the left and turning off the generated content.
@media screen and (max-width: 600px) {
dl.definition-table dt:after {
display: none;
}
dl.definition-table dd {
display: block;
float: right;
margin-top: 1rem;
}
dl.definition-table dt {
display: block;
float: left;
clear: left;
}
dl.definition-table dt img {
vertical-align: middle;
}
}
Like all current responsive solutions, this code is neither all-encompassing nor perfect. It is best suited to represent tables with few initial “rows” but many columns: multiple table rows are simply more definition lists with the same class names and structure.
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.