Making your HTML Tables Responsive

Tables aren’t fun. Especially on responsive sites. Divs though, they’re wonderful! Lists? Even better! It all flows wonderfully with the grid system and our little divs and li’s will neatly reorganize themselves following the grid system. Table cells though. Those little runts are bound by the rows they’re defined in, which throws the grid system out the door. Suddenly our defined table row <tr> tags are causing all of our tds to force themselves onto one row of data, shrinking and squishing all our content to fit.

Now we have a cluster of content that looks absolutely awful:

Full Width Table Row:
full width table row

Squished Table Row:
squished table row

Related: The Future of Responsive Web Design

How We Make HTML Tables Responsive:

Now, here at the Demac Media factory of little front-end magicians, we’ve come up with a neat little way to make these tables flow responsively, and follow a grid without having to replace the entire thing with divs. (I know, that’s a very viable option…but for a system like Magento? Not always the best.*) It’s not entirely innovative, it’s probably been done before, but it’s still a neat little trick you should try out.

Table pieces:

Tables consists of the following tags: (Some you’ll see more than others, but it’s always a good idea to make sure we cover them all because certain browsers or editors will automatically create these tags if they’re missing)

<table>
    <thead>
        <tr>
            <th>Table Header 1</th>
            <th>Table Header 2</th>
            <th>Table Header 3</th>
        </tr>
    <thead>
    <tbody>
        <tr>
            <td>Table Cell 1</td>
            <td>Table Cell 2</td>
            <td>Table Cell 3</td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
           <td colspan="3">Footer Cell</td>
        </tr>
    </tfoot>
</table>

Let’s make them friendlier to skin:

The basis of letting tables become responsive is to turn them all into blocks as soon as our window hits a certain breakpoint.This allows us to apply %width rules, and to let the browser know that these blocks should reflow vertically if it goes beyond a certain width.

We’ll use this rule to achieve it:

display: block;

But Tony, if we set them all to display block, our table’s going to look weird!

I know. We only want to take advantage of the display:block when we’re below a certain breakpoint.
So realistically, you’ll want to use this:

@media only screen and (max-width: <your breakpoint>px) {
    table {
        display: block;
    }
}

Tony! I built my site mobile-first, because I’ve read all of Demac’s blog posts! I know responsive! You’re wrong!

Okay, okay, I know. We should build all our sites mobile first if we’re building a responsive site. That was definitely not the correct or best way to approach this, but it highlights the basis of our little hack when you want to make your HTML tables responsive. The idea is right.

What you’ll want though is to set every element of the table to display: block, and then as your site hits a breakpoint set your table to behave like a regular table again. In other words, we’ll initialize the table pieces as blocks rather than tables, and then set them to their respective table display properties when our breakpoints allow us to.

Related: Looking for The Best Responsive Sites? Here are 15 to Inspire You!

The rules will look as follows:

table, thead, tbody, tfoot, tr, th, td {
    display: block; /* Set all of our table elements to display type block */
}

/* And here we will set our table to act normally after we hit 1024px */
@media only screen and (min-width: 1024px) {
    table { display: table; }
    thead { display: table-header-group; }
    tbody { display: table-row-group; }
    tfoot { display: table-footer-group; }
    tr { display: table-row; }
    th, td { display: table-cell; }
}

Now you can style your table cells as if they’re nested divs. We’ve mimicked the behaviour of divs with our table tags.

So for example, a little fun grid like this is now possible:

td:first-child {
    box-sizing: border-box;
    width: 25%;
    float: left;
    padding: 10px;
}

td:nth-child(2), td:nth-child(3), td:nth-child(4) {
    padding: 10px;
}

td {
    padding: 15px;
    margin: 15px;
    border: 1px solid #ddd;
}

And that’ll give us some little fun grids like this one (It’s not the prettiest, but I’m certain most of you are more creative than I am):

responsive table

Oh and of course, to prove my point, here’s what happens if I remove display: block altogether from those rules:

not a responsive table

Looks horrifying, doesn’t it?

There You Have It!

Remember, your tables should become responsive when your windows hit a certain breakpoint. With this fun little hack of mine, as your site hits that breakpoint your tables will be acting as blocks rather than tables. They will then at that point be set to their respective table display properties if you follow what I’ve outlined in this post. Get creative and arrange them into grids! Comment below if you have any questions for me.

Related: Responsive Grid Downloads for Designers

* Most of the order review, shopping cart, and mini cart templates of Magento uses a table, with the class “data-table”. These tables are actually required by Magento core, so we don’t recommend you replace the table tags with div tags. It’s one of the reasons why we recommend using this css hack above in order to save you some trouble!