I was challenged by a client project to build properly responsive tables - that is, tables that had a fairly different design when running mobile than desktop, but remaining smoothly adaptive. And for extra points, it had to be mobile-first. JavaScript was a no-no. Our designs demanded a card-like layout for mobile, with a more traditional table for desktop.

There are a few examples of how to do this out there, but these tend to be desktop-first traditional tables that adapt to mobile - arguably a sensible approach as this follows the semantic markup. But can it be done mobile first? Why, yes it can.

Step 1, we need to "undo" the table; that is, stop the various elements of a table being... well, table-like.

In our markup, we need to make use of the data- attribute to double down on the table heads so that we can do a little CSS trickery. Our table headings (in the markup) are only displayed in desktop. In mobile, we snatch the "card" headings from the data-title attribute and glue it before the table cells.

  <table class="table">
  <thead class="table__head">
    <tr class="table__row">
      <th class="table__cell table__cell--head" scope="col">Name</th>
      <th class="table__cell table__cell--head" scope="col">Version</th>
      <th class="table__cell table__cell--head" scope="col">Release date</th>
      <th class="table__cell table__cell--head" scope="col">Release #</th>
  <tbody class="table__body">
    <tr class="table__row">
      <th class="table__cell table__cell--head" scope="row" data-title="Name">
        El Capitan
      <td class="table__cell" data-title="Version">
      <td class="table__cell" data-title="Release date">
      <td class="table__cell table__cell--head" data-title="Release #">

Note, the follow examples use SCSS flavoured CSS. Read the transpiled CSS to view the output CSS in the CodePen embedded below if that's not your thing.

Now to the CSS, and we turn everything into blocks in our CSS:

  &__body, &__row, &__cell {
    display: block;

Now that each row is a block, it'll naturally stack with all the cells belonging to that row (also now blocks) stacking inside, giving us our mobile-first card view.

Step 2, we use the data-title attribute as content for a :before for each cell:

  &__cell[data-title]:before {
  display: inline-block;
  content: attr(data-title) ":";

Now we have the mobile-first table rendering the way we want.

Step 3, of course, is turning in back into a regular table for desktops. To do this, we need to select the elements that make up the original table and tell the browser, actually, stick it back together for us. In modern browsers we can use display: table-header-group, display: table-row and display: table-cell. We also need to hide our data-attribute augmented titles. This is all done inside the breakpoint:

  @include breakpoint(medium) {
    &__head {
      display: table-header-group;
      visibility: visible;
    &__row {
      display: table-row;
      .table__cell {
        display: table-cell;
    &__cell[data-title]:before {
      display: none;

Pop out the following codepen so that you can resize the browser and see the responsivenes in action (mobile breakpoint is at 768px):

Note, legacy browsers (pre-HTML5) will display a regular 'desktop' table regardless of screen-size. If you're trying to do responsive layouts in Internet Explorer 8 or less... you can't. Not without JavaScript. IE8 was pre-mobile-web. Don't even try.

2,500 0 4