Monthly Archives: July 2019

Responsive Table Layout with CSS Grid

Making tables responsive to screen size has always been a bit an issue with no perfect solution for all situations.

One option is to hide some less important data as the screen size gets smaller, and then allow the user to expand the data somehow if they want to see everything.

Or you could set the table to scroll horizontally if the screen size is too small.

These options may be necessary for big complex tables of lots of data, but if you are dealing with a simple table, I find that using CSS grid offers an elegant solution.

See the Pen Simple Responsive Table Layout with CSS Grid by Lisa Catalano (@lisa_c) on CodePen.



In this example I have two sections that are grids and use the same layout which is set up with the term-grid class. The header section is a grid, and each line in the data section is a grid. Please note that I’m using Vue.js to display the data and keep the html clean, but it is unrelated to the grid. If I was not using Vue, each line of data would be repeated with its own grid. Below is an example of what the HTML for one definition without Vue would look like.

<div class="term-grid">
  <label>Lorem</label>
  <div class="definition">ipsum dolor sit amet consectetur adipisicing</div>
  <div class="alternate">something</div>
</div>

The important CSS is to add display: grid to the container that you want to be a grid. In my example, this is done with the class term-grid. You also want to set up the size of each column in the grid using grid-template-columns. I am using fractional units to set up the different column widths. Using fractional units means that the columns will grow and shrink proportionally as the screen-size changes. The grid-gap is simply the gap in between the columns.

.term-grid {
  display: grid;
  grid-template-columns: 1fr 4fr 1fr;
  grid-gap: 2em;
}

When the user is on a small screen, you can easily change the layout to be a column of data instead of a row. There are different ways to achieve this, but the way I handle it is to change the grid-template-columns property to just be 1fr. Each of the data pieces in the grid will take up the full width of the screen, or to be more accurate, the full width of its parent container.

@media (max-width: 600px) {
  .term-grid {
    grid-template-columns: 1fr;
    grid-gap: 0.5em;
  }

  .grid-header {
    display: none;
  }

  .alternate {
    margin-top: -10px;
    font-style: italic;
    order: 1;
  }
  
  .definition {
    order: 2;
  }
}

I’m also hiding the headers and changing the order and styles slightly of the second and third data cells. This is not going to be something you always want to do, but because the 3rd column is optional, I wanted it to show under the term and be italics so it doesn’t look like part of the definition.

See the Pen Simple Responsive Table Layout with CSS Grid by Lisa Catalano (@lisa_c) on CodePen.



I’m embedding the Pen a second time with code to force the screen to be smaller, so you can see the mobile version. If it not showing for you, you can open the pen in its own tab and play with the screen size on your own.

The code that is defining the grid and the small changes for mobile are really just a few lines, and I really like this solution for simple tables of data.