CSS Responsive Tables

In this tutorial we're going to look at how we can use tables on responsive layouts and how can we make these tables usable on mobile devices. When tables are on responsive layouts you will find that you face a number of problems such as:

  • Too many columns
  • Words overflowing the cells
  • Column width being too small
  • If you have a lot of rows, as you scroll you can't see the column headers

In this tutorial we will hopefully fix all these problems by using CSS responsive solution. First we need to create a table we can use to test responsive, so here's a list of the top 5 movies on IMDB.

<table>
  <thead>
  <tr>
    <th>Movie</th>
    <th>Release Date</th>
    <th>IMDB Rating</th>
    <th>Director</th>
    <th>Staring</th>
  </tr>
  </thead>
  <tr>
    <td data-title="Movie">The Shawshank Redemption</td>
    <td data-title="Release Date">1994</td>
    <td data-title="IMDB Rating">9.3/10</td>
    <td data-title="Director">Frank Darabont</td>
    <td data-title="Staring">Tim Robbins, Morgan Freeman, Bob Gunton</td>
  </tr>
  <tr>
    <td data-title="Movie">The Godfather</td>
    <td data-title="Release Date">1972</td>
    <td data-title="IMDB Rating">9.2/10</td>
    <td data-title="Director">Francis Ford Coppola</td>
    <td data-title="Staring">Marlon Brando, Al Pacino, James Caan</td>
  </tr>
  <tr>
    <td data-title="Movie">The Godfather: Part II</td>
    <td data-title="Release Date">1975</td>
    <td data-title="IMDB Rating">9/10</td>
    <td data-title="Director">Francis Ford Coppola</td>
    <td data-title="Staring">Al Pacino, Robert De Niro, Robert Duvall</td>
  </tr>
  <tr>
    <td data-title="Movie">The Dark Knight</td>
    <td data-title="Release Date">2008</td>
    <td data-title="IMDB Rating">9/10</td>
    <td data-title="Director">Christopher Nolan</td>
    <td data-title="Staring">Christian Bale, Heath Ledger, Aaron Eckhart</td>
  </tr>
  <tr>
    <td data-title="Movie">Schindler's List </td>
    <td data-title="Release Date">1993</td>
    <td data-title="IMDB Rating">8.9/10</td>
    <td data-title="Director">Steven Spielberg</td>
    <td data-title="Staring">Liam Neeson, Ralph Fiennes, Ben Kingsley</td>
  </tr>
</table>


<table>
  <thead>
  <tr>
    <th>Movie</th>
    <th>Release Date</th>
    <th>IMDB Rating</th>
    <th>Director</th>
    <th>Staring</th>
  </tr>
  </thead>
  <tr>
    <td data-title="Movie">The Shawshank Redemption</td>
    <td data-title="Release Date">1994</td>
    <td data-title="IMDB Rating">9.3/10</td>
    <td data-title="Director">Frank Darabont</td>
    <td data-title="Staring">Tim Robbins, Morgan Freeman, Bob Gunton</td>
  </tr>
  <tr>
    <td data-title="Movie">The Godfather</td>
    <td data-title="Release Date">1972</td>
    <td data-title="IMDB Rating">9.2/10</td>
    <td data-title="Director">Francis Ford Coppola</td>
    <td data-title="Staring">Marlon Brando, Al Pacino, James Caan</td>
  </tr>
  <tr>
    <td data-title="Movie">The Godfather: Part II</td>
    <td data-title="Release Date">1975</td>
    <td data-title="IMDB Rating">9/10</td>
    <td data-title="Director">Francis Ford Coppola</td>
    <td data-title="Staring">Al Pacino, Robert De Niro, Robert Duvall</td>
  </tr>
  <tr>
    <td data-title="Movie">The Dark Knight</td>
    <td data-title="Release Date">2008</td>
    <td data-title="IMDB Rating">9/10</td>
    <td data-title="Director">Christopher Nolan</td>
    <td data-title="Staring">Christian Bale, Heath Ledger, Aaron Eckhart</td>
  </tr>
  <tr>
    <td data-title="Movie">Schindler's List </td>
    <td data-title="Release Date">1993</td>
    <td data-title="IMDB Rating">8.9/10</td>
    <td data-title="Director">Steven Spielberg</td>
    <td data-title="Staring">Liam Neeson, Ralph Fiennes, Ben Kingsley</td>
  </tr>
</table>

You'll notice it's just a normal table with an added attribute to the table cells which we can use for the cell titles when the table is responsive all by using CSS. This is because in CSS you have access to display the content of a HTML attribute in pseudo classes of :before and :after using the content property. If we would to view this table on a mobile device it will look like this

As you can see the table isn't really usable on a mobile device and the last column has too much text in it that you can't read things correctly. So now we need to change the table styling on mobile devices by using media queries so that it looks like this.

First we define the media query that we need to use on mobile devices.

@media screen and (max-width: 320px) 
{
    // Style the table on mobile devices
}

Then we can change the styling of the table to behave on a mobile device. First we're going to hide the table headers as we are moving the headers next to the data instead of above it.


table thead 
{
    display: none;
}

We're moving the cells in the table to go from next to each to on top of each other, so we need to add some gaps between the rows by rows by adding a margin to the bottom of these rows.


table tr 
{
    margin-bottom: 10px;
    display: block;
    border-bottom: 2px solid #ddd;
}

To move the cells to be on top of each other we need to change the cells to be display: block; and move the text to the right of the cell so there's space for the title on the left.


table td 
{
    display: block;
    text-align: right;
    font-size: 13px;
    border-bottom: 1px dotted #ccc;
}

table td:last-child 
{
    border-bottom: 0;
}

Next we can add the title of the cell to the left of the data by using the :before pseudo class and adding the content data-title.


table td:before 
{
    content: attr(data-title);
    float: left;
    text-transform: uppercase;
    font-weight: bold;
}

Below is the full code you will need to use in your CSS to create these responsive CSS tables.


@media screen and (max-width: 320px) 
{
    table thead {
      display: none;
    }

    table tr {
      margin-bottom: 10px;
      display: block;
      border-bottom: 2px solid #ddd;
    }

    table td {
      display: block;
      text-align: right;
      font-size: 13px;
      border-bottom: 1px dotted #ccc;
    }

    table td:last-child {
      border-bottom: 0;
    }

    table td:before {
      content: attr(data-title);
      float: left;
      text-transform: uppercase;
      font-weight: bold;
    }
}

Below is the codepen used in the demo so that you can resize the HTML section to see how the table view will change on mobile devices. See the Pen QNvBRd by Paul (@paulund) on CodePen.

More Examples

Do you need more examples of how responsive CSS tables works here's a collection of the best codepen examples. Responsive CSS Tables

UpChecker

Reliable uptime monitoring and instant alerts for any website downtime.

  • Uptime Monitoring
  • Performance Monitoring
  • SSL Certificate Alerts
  • Domain Monitoring
  • DNS Checker
  • XML Sitemap Monitoring