Responsive Tables

A few smart folks have already put together their thoughts on responsive tables and, while I think the proposed methods are pretty good, I think there might be room for improvement. As such, I’ve been tinkering for a while and came up with the following strategy when it comes to tables.

Step 1: Use data-* attributes to hold information about the column header(s) associated with the markup:

```html
Name Email Dept, Title Phone
Smith, Laura Biology, Director 123-456-789
Johnson, Ron Purchasing, Director 123-456-7891
```

Step 2: When the screen is below a certain threshold, set the table elements to display: block (thereby linearizing the table), hide the thead where assistive tech won’t see it, and use generated content to expose the data-* attributes. Here’s a snippet of SASS & Compass that does that:

```scss // undo tables for small screens // $break-4 is the px-width break at which you want to cut it off @media (max-width: px-to-ems($break-4 - 1px)) {

// make each table separate from other ones table {

border: 0; @include trailing-border; padding-bottom: 0; display: block; width: 100%;

// make sure captions are displayed caption { display: block; }

/* * wipe the thead from the face of the earth * modern screen readers will expose the * generated content */ thead { display: none; visibility: hidden; }

/* * make everything display block so it * aligns vertically */ tbody, tr, th, td { border: 0; display: block; padding: 0; text-align: left; white-space: normal; }

// give each row a little space tr { @include trailer; }

/* Labeling * adding a data-title attribute to the cells * lets us add text before the content to provide * the missing context * * Markup: *

Content Here * * Display: * Column Header: Content Here */ th[data-title]:before, td[data-title]:before { content: attr(data-title) “:\00A0”; font-weight: bold; } th:not([data-title]) { font-weight: bold; }

// hide empty cells td:empty { display: none; } } }

<p>We’ve been using this approach on a number of sites currently in development and it works really well. I put together <a href="http://codepen.io/aarongustafson/pen/ucJGv">a demo of this technique</a> so you could play around with it yourself.</p>
<p><strong>Notes:</strong></p>
<ol>
<li>I chose to use a <code class="html">data-*</code> attribute (<code class="html">data-title</code>) instead of <code class="html">title</code> as the <code class="html">title</code> attribute could be read out by assistive technology and in the case of the <code class="html">thead</code> being available as well (when not <code class="html">display: none</code>), resulting in the information being read twice (which is not ideal). <a href="http://www.paciellogroup.com/resources/articles/WE05/#slide9">That’s not a certainty however</a>, so you could choose to go the <code class="html">title</code> route if that’s your preference. I prefer to avoid the potential issue.</li>
<li>If you have multiple header rows over a cell (say a parent row and then a child row), I’d recommend making the <code class="html">data-title</code> something like “Parent Header - Child Header.<span class="final quote">”</span></li>
<li>While you could use JavaScript to auto-generate the <code class="html">data-title</code> attributes by referencing the column headers, I feel this is information that should exist even if JavaScript is not available. You may disagree.</li>
</ol>