Cover image by Tolga deniz Aran
This is some CSS and JavaScript which allows tables of any size to render on mobile as a simple two-column table, eliminating horizontal scroll.
Note that I didn't invent (or rediscover) this technique - it's an adaptation from where I first encountered it, to take into account edge cases and awkward content.
Don't bore us, get to the chorus:
How this works
Your table doesn't need any specific markup for this to work, in most cases. The JavaScript makes the assumption that the first row describes the rest of the table and attempts to connect every following table cell with its corresponding header cell.
It adds a data-label
attribute to the cells, the content of which is a plane text version of whatever appears in the corresponding header.
When it's time for the table to switch to mobile mode, the first row is hidden and the table and its elements are all switched to display: block
. This creates a veeeeery long table with just table cells, all the way down.
Inside each table cell are three elements:
- A
before
element, the contents of which is the text within thedata-label
attribute - One or more elements which actually live inside the table cell. This could be a single text node or a heading and a list: I'm not going to tell you how to fill your table cells
- An
after
element which has your Grandfather's clearfix on it, like it's 2005
Using floats for layout? In the 21st century?
Yeah, I tried a few other methods first. Here's how it went:
- Flexbox: worked well until I had multiple paragraphs within the same table cell. Then it started forming multiple columns. Go down that road and you've got yourself another table.
- Positioning: worked until the header text wrapped. Then it started getting illegible fast
- Grid: no, I didn't try grid. I'll leave that for the professionals.
Floating allows two columns of text to be as long as you like and to sit side by side.
Where this breaks down
As you might have seen from the notes inside the table cells, certain colspan
and rowspan
combinations are not handled well by the JavaScript. It would be perfectly possible to make them work but ... I couldn't be bothered. It wouldn't be easy to get them to work, which is why I've left it as an exercise for the reader (this is what people say, right?).
Also, as the text which represents the header cell has all the HTML stripped out of it, any markup there will not appear on the mobile version of the table.
Perhaps there's a version of this where instead of data-label
attributes, the contents of each cell are wrapped in an element, the contents of each corresponding header cell is placed in a preceding element and these two elements are laid out using flexbox. Seems like a faff, if you ask me.
Workarounds
When I said in most cases
above, you can fix the issue above with some added markup. In HTML, it's possible to explicitly associate a table cell with another cell, to show they have a relationship. We do this using the headers
attribute.
When the JavaScript is attempting to pull in the correct header data, it checks for a headers
attribute first, and uses that in preference to its best guess.
What this means for tables with a lot of rowspan
and colspan
attributes is that you can ensure the correct content appears on mobile by using the headers
attribute. But you only need to do it on cells which appear after the cells which won't stay in their lane. The ones before should work fine.
Top comments (0)