1 Thing A Week 1 Thing
A Week

Using CSS to make responsive tables with headers that are readable An alternative to just stacking headings when on a mobile device

Week 132.0 — 4th May '20

Only once have I posted something that could even be considered technical, back when I refreshed 1 Thing A Week. That was quite some time ago, and I was never sure if this was going to be a place where I'd post content related to my day job but in reality there's no better place for me to do it.

It's been at least 10 years that I've been looking at responsive web design and over the past few weeks I've been testing to see just how powerful it can be.

Responsive tables

One thing I've always found tough to work with is tables. Collapsing them on mobile is very easy, but you end up with stacked headers that don't line up properly with the content they relate to.

There are plenty of examples of how to make responsive tables, but none really satisfied my in the way deal with column headers.

  • Accessible, simple, responsive tables from CSS-Tricks (works for pricing or comparison data)
  • "Responsive" tables from W2Schools (no re-flow for better readability, just introduces a scrollbar)
  • Simple Responsive Tables by Matt Smith is my favourite of the other solutions I've seen by using the `data` attribute, every row is treated to appear like it has it's own header (introduces a lot of duplication)

So there are some solutions, but for long sets of tabular data, either it introduces more text to read or isn't what I would consider truly responsive. Before now, this is what most tables on 1 Thing A Week look like on a mobile device:

Not perfect, but never used enough for me to put the time and effort into 'fixing' them. Ten this past week I had a light bulb moment after looking at the new calendar view. In this case, a responsive table isn't necessary, but where it is I thought about concatenating the header content into a readable sentence to give an indication of what is in each row without having to repeat the content or introducing a horizontal scrollbar.

Either by using JavaScript or revealing the right header at different break points, we could reveal a row that has the column titles bunched up together which would stack really nicely. This isn't that readable though and using JavaScript is an overhead that isn't required.

How do you make responsive headers more readable?

Let's take it from just a list of words

The solution isn't difficult, it's just about understanding the flexbox model and how pseudo elements work. By combining the two, we can easily chain the headers into a readable header like the example above. Here's the basic CSS you would need to achieve this:

/* Use flexbox to remove the headers from their columns */ table thead tr, table tbody:first-child tr:first-child { display: flex; text-align: left; } /* Remove the right border from all but the last cell */ table thead tr th:not(:last-child), table tr:first-child th:not(:last-child) { border-right: 0; } /* Let the last cell take up all of the available space, bringing all the content next to each other */ table thead tr th:last-child, table tr:first-child th:last-child { flex: 1; } /* Remove any LEFT padding from all except the first cell */ table thead tr th:not(:first-child), table tr:first-child th:not(:first-child) { padding-left: 0; } /* Remove any RIGHT padding from all except the last cell */ table thead tr th:not(:last-child), table tr:first-child th:not(:last-child) { padding-right: 0; } /* Add a comma and a space before to all but the first cell */ table thead tr th:not(:first-child):before, table tr:first-child th:not(:first-child):before { content: ',\00a0'; } /* Add ' & ' before the last cell */ table thead tr th:last-child:before, table tr:first-child th:last-child:before { content: '\00a0\0026\00a0'; }

I've created a more complex solution as a gist on GitHub that has the basic HTML and the CSS to remove white space and introduce an alternating background colour to make the table easier to scan. You should be able to lift the CSS and apply it to any table. There's a resizable demo I've added to JSFiddle so you can try it out there too.

Even if you don't use the <tbody> HTML tags, looks like all browsers inject it anyway. By default, the code is wrapped in a media query which means it only applies to screens less than 700px wide. Either remove that restriction or adjust it to whatever your needs are.

More from 1 Thing A Week
« Creating stop motion animations with an iPhone and Siri Shortcuts BuzzFeed's 'Worth It' How to use the prefers media query in CSS Thoughts on Boris Johnson's 'Stay Alert' briefing »



Quick links and commentary on interesting articles, videos and more throughout the week.

  1. 132.1 – Monday
    1. De Rossi: Captain Future Golazzo on podcasts.apple.com
    2. Photos of Arizona, the Grand Canyon state theatlantic.com
  2. 132.2 – Tuesday
    1. 100 Dates, the post-quarantine bucketlist   CA$35+ Marie on kickstarter.com
  3. 132.3 – Wednesday
    1. "Space Force" teaser trailer Netflix on youtube.com
  4. 132.4 – Thursday
    1. Game Changer @banksy on instagram.com

Jump to notable items for Week #131, Week #133 , view the notable archive or my favourites.

About 1 Thing A Week

A website curated by @cchana bringing you 1 Thing A Week, delivered every Monday morning.

You can find a list of all articles in the archive, or read the most popular.

Find out more about 1 Thing A Week or read the privacy policy.


Visit the market and support 1 Thing A Week.

You can find 1 Thing A Week on Twitter, Facebook, Instagram & Reddit