Responsive table with CSS grid-template-areas

Responsive table with CSS grid-template-areas

Utilizing CSS grid for more complex tables

Building responsive tables used to be tricky. It all depends on design, but before we often had to use CSS properties like *display: block, `float: left*,position: absolute` etc. to display elements properly for mobile devices. Flexbox makes things easier but there’s an even better solution, which is CSS grid. In this article, I’ll focus particularly on grid-template-areas.

Photo by [Daniel McCullough](https://cdn.hashnode.com/res/hashnode/image/upload/v1621430323950/S8IFixpKh.html) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)Photo by Daniel McCullough on Unsplash

Let’s take a look at a specific example. Below we have a normal HTML table that works the same on desktop and tablet. It contains 5 columns. We can see an icon, document type (Invoice), number, price and download icon.

table (tablet view)table (tablet view)

HTML could look like this:

<table class="invoices-table">
  <tbody>
    <tr>
      <td class="td-type-icon">
        <span class="icon-invoice"></span>
      </td>
      <td class="td-type">Invoice</td>
      <td class="td-number">#479508274018573</td>
      <td class="td-price">25 EUR</td>
      <td class="td-invoice">
        <a href="" class="download-icon">Download invoice</a>
      </td>
    </tr>
  </tbody>
</table>

On a mobile phone we can’t display all the information in one row. We want to adjust it slightly and put “Invoice” and its number together in one column.

grid (mobile)grid (mobile)

We can achieve it quite easily with CSS grid and thus avoid fiddling with older techniques I mentioned at the beginning. To have a better control over the cells, we can use the grid-template-areas property.

The **grid-template-areas** CSS property specifies named grid areas, establishing the cells in the grid and assigning them names.

This means we can assign each cell in the table a name.

grid-area

There’s ***grid-area* property for that. Given the HTML above, our simplified CSS would look like this:

.td-type-icon{
  grid-area: icon;
}

.td-type{
  grid-area: doc;
}

.td-number{
  grid-area: number;
}

.td-price{
  grid-area: price;
}

.td-invoice{
  grid-area: invoice;
}

We’ve assigned the names for each cell, so we can use them now in the grid.

grid-template-areas

We want a table row to behave on mobile as a grid, and on bigger screens it would be normal table-row, so we define a breakpoint for that.

tr{
  display: grid;
  grid-template-columns: 35px 1fr 25% 35px;
  grid-template-rows: auto;
  **grid-template-areas:
  ". doc . ."
  "icon number price invoice";**
  align-items: center;
  @extend %u-p-3;

  @include breakpoint('from-tablet') {
    position: relative;
    display: table-row;
  }
}

Let’s break this down a bit more.

We define also width for the columns. Notice on mobile we want only 4 columns. Fr is a fractional unit and 1fr stands for 1 part of the available space, which we give to 2nd column.

grid-template-columns: 35px 1fr 25% 35px;

Since we want to display document type and its number together in one column, we can do the following:

**grid-template-areas:
  ". doc . ."
  "icon number price invoice";**

The dot represents an area that is not named, therefore empty and the space will be distributed accordingly. Basically we defined 2 rows and 4 columns, where the doc and number are in the 2nd column. This is how it looks like:

Great, but how do we center the items vertically? We can span the grid row by 2, since we have 2 rows defined.

grid-row: span 2;

***span && [ &lt;integer&gt; || &lt;custom-ident&gt; ]** Contributes a grid span to the grid item’s placement such that the corresponding edge of the grid item’s grid area is n lines from the opposite edge.*

That means we have to span 1st, 3rd, and 4th column:

.td-type-icon{
  grid-area: icon;
  grid-row: span 2;
}

.td-price{
  grid-area: price;
  grid-row: span 2;
}  

.td-invoice{
  grid-area: invoice;
  grid-row: span 2;
}

Tip

In all modern browsers, you can also open developer tools and see that we turned the table row into grid. You can hover over the ‘grid’ label or activate it to see visual guide.

grid highlighting in Chromegrid highlighting in Chrome

Summary

Apart from using CSS grid for styling the main layouts and grids we can use it also to transform HTML table row to grid. It’s handy to display more complex tables on mobile devices, because we can assign each cell a name using grid-area and then apply them in grid-template-areas. With this grid property we can see visual representation of our table and then simply align the rows/columns if needed.

It is fair to say that it’s better to think inside the box sometimes! :)