Responsive table layout with only CSS


Very different type of post because I want to show you how to create a fully responsive table layout with only CSS. This will help you to display your tables, large or small, on every screen in a pleasant way.

The issue

First, let’s say I’m viewing Wikipedia on my iPhone, I’m looking through the episode list for Star Trek: The Next Generation, and the table has a lot of columns and data. There ends up being a lot of back-and-forth side swiping, device flipping, and general annoyance as I muddle through that user experience.

So, it’s an issue that exists broadly across the web, even though there are several responsive table solutions available. Here a demo of the solution I found.

Demo Responsive table layout with only CSS

Create a basic table

So, we’ll create the same table above with some generic HTML

  <caption>Statement Summary</caption>
      <th scope="col">Account</th>
      <th scope="col">Due Date</th>
      <th scope="col">Amount</th>
      <th scope="col">Period</th>
      <td>Visa - 3412</td>
      <td>03/01/2016 - 03/31/2016</td>

After that, our table has four columns. Let’s add some basic CSS selectors to better define the table layout:

table {
  border: 1px solid #ccc;
  border-collapse: collapse;
  margin: 0;
  padding: 0;
  table-layout: fixed;
  width: 100%;

table tr {
  background-color: #f8f8f8;
  border: 1px solid #ddd;
  padding: .35em;

table th,
table td {
  padding: .625em;
  text-align: center;

Responsive time

First, we’ll add a data-label attribute to each data cell with a value that represents that column’s name. That will be used for labeling purposes in the responsive layout.

<td data-label="Account">Visa - 3412</td>
<td data-label="Due Date">04/01/2016</td>
<td data-label="Amount">$1,190</td>
<td data-label="Period">03/01/2016 - 03/31/2016</td>

Now, we can begin writing a CSS media query:

@media screen and (max-width: 600px) {
  table thead {
    border: none;
    clip: rect(0 0 0 0);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px;
  table tr {
    border-bottom: 3px solid #ddd;
    display: block;
  table td {
    border-bottom: 1px solid #ddd;
    display: block;
    text-align: right;
  table td::before {
    content: attr(data-label);
    float: left;

In smaller viewports the <tr> and <td> elements will display as block-level and not as table rows and cells. And the ::before pseudo-element now serves as a label.

So, here’s our table (flip your device screen between portrait and landscape view):

Wrap up

In conclusion, this is a simple way to get a nice responsive table layout with only CSS in particular for mobile devices. For any question, please use the form below or create a post in the Forum.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.