How to create responsive table in modern way

Yuki C.
4 min readSep 4, 2018

--

Table is an important tool for representing data, however, for small screens e.g. mobile and tablet, it is also crucial to represent data in different way. Otherwise, it turns into chaos!

Oh, no! My ice-cream!

New friend: Flexbox

For modern browsers, we all can use flexbox to create responsive tables! If you want to know more about flexbox, you can always view the superb guide from CSSTricks!

First, this is what we want to do:

Desktop, tablet and mobile version of this table.

Don’t care about the tours right now, it just copy and paste from the web (although I also hope to go there lol)!

First, we can create the structure of the table. The most tricky one is the nested table in “United States”, we will use nested div to cover that:

For simplicity purpose, we use Flag Icon CSS to create flags here. For production, it should use SVG or SVG sprites to do so, as we only need few flags (to save more bandwidth!).

For nested table of “United States”, you can see we used different class column to create it.

Then, our lovely CSS!

For normal rows, we use .flex-table and .flex-row to wrap them, and the rows are equally 25%, which means 100% / 4.

For nested rows, the first cell is 25%, then we use .column as the container, width 75% and wrap tables with .rowspan and .flex-table.

The most important one is box-sizing:

div {
box-sizing: border-box;
}

So that all paddings, borders etc. will not count in 100%. If you have not use this code and you added 0.5em padding, you will need to calculate the width yourself, e.g. calc((100% — 0.5em) /4) in your CSS.

The 2nd important one is flexbox layout!

display: flex;
flex-flow: row wrap;

As you can see, we use flexbox for this layout, and all cells are in a row, so we need to add this code to .flex-table.

Flex-flow is the shorthand for flex, the first row is flex-direction, which means all cells become rows automatically.

The second one is flex-wrap, so if all elements exceed width of container, it will automatically wrapped to second line.

Last but not least, the border settings are important too!

Since div’s border will overlap, so all the borders should be unique. This time, I have set the bottom and right border in .flex-row and left border in .flex-table. So the bottom border will create top border for the next row :)

$table-header: #1976D2;
$table-header-border: #1565C0;
$table-border: #d9d9d9;
.flex-table {
display: flex;
flex-flow: row wrap;
border-left: solid 1px $table-border;
transition: 0.5s;
&:first-of-type {
border-top: solid 1px $table-header-border;
border-left: solid 1px $table-header-border;
}
&:first-of-type .flex-row {
background: $table-header;
color: white;
border-color: $table-header-border;
}
}

Here comes our final product:

Newcomer: Grid layout

Not all the browsers can use this method, only 80% of browsers support it. But, why don’t we have a try? Let’s try to change the previous flexbox table to CSS grid layout!

First, delete all flexbox-related properties and add:

.flex-table {
display: grid;
grid-template-columns: repeat(auto-fill, 25%);
}

After added repeat(auto-fill, 25%), it will automatically generate rows of 25%.

The most tricky one is the nested table in tablet version, which the first cell will changes to 100%. Do we need to create grid of 100% this time? No, we will create 33.33%, that means 3 cells in 1 row.

.flex-table {
display: grid;
grid-template-columns: repeat(auto-fill, 33.33%);
grid-template-rows: repeat(auto-fill, 100%);
}
.first {
grid-column-start: 1;
grid-column-end: 4;
}

What does that means? That means when a div has .first class, which is the first cell, it will occupied 1–3 grid.

That means, when we created 33.33% * 3 grid in 1 row, the first cell will occupied 1 full row. Then the next row starts, all the remained items will go to next row.

Here comes our final results!

How about accessibility?

Well, using div to create table is neither native nor semantic. The best way to create table is still using the native <table> tag. You still can use the div method, but don’t forget the aria-labels!

If you want to achieve that using native method, here comes the responsive version:

Just like back to 1990s! But you can see that, less HTML and CSS to get the same result, and save more time for both accessibility (Explore more about accessibility here) and development.

What would you choose to create your fancy responsive table these days? Welcome to express your opinions!

--

--

Yuki C.

I am a self-taught front end developer based in Hong Kong! Mostly focused in front-end tech, e.g. React and SASS. Welcome to connect with me!