In this tutorial, we’ll learn how to build a stylish table and modify its layout to adapt to various screen sizes.
The data presented in our table will come from the IMDb platform and list a few of Steven Spielberg’s movies.
Responsive Tables in HTML
Tabular data should be structured in one way: with the HTML table elements. This is the semantically correct approach, but it can give us some serious stylistic challenges. Tables are notoriously inflexible where responsive layouts are concerned.
There are several solutions to the issue: scrollable containers wrapping the table, collapsible cells, using different (less semantic) markup. We’re going to use Flexbox to display our table cells in a grid layout on smaller screens.
1. Begin With the HTML Markup
The markup will be straightforward: a table with six rows inside a container.
Here’s how it’ll look:
<div class="container"> <table> <thead class="visible@l"> <tr> <th>Title</th> <th>Year</th> <th>Stars</th> <th>Plot</th> </tr> </thead> <tbody> <tr> <td> <strong class="hidden@l">Title:</strong> ... </td> <td> <strong class="hidden@l">Year:</strong> ... <img width="140" height="209" src="https://webdesign.tutsplus.com/tutorials/..." alt="https://webdesign.tutsplus.com/tutorials/..."> </td> <td> <strong class="hidden@l">Stars:</strong> ... </td> <td> <strong class="hidden@l">Plot:</strong> ... </td> </tr> <!-- more table rows here --> </tbody> </table> </div>
Notice the visible@l
and hidden@l
classes. These will help us toggle specific elements depending on the viewport size.
2. Add Styles
Mostly, we’ll follow a mobile-first approach for our styles. As mentioned above, we’ll need two helper classes:
@media (max-width: 999px) { .visible\@l { display: none; } } @media (min-width: 1000px) { .hidden\@l { display: none; } }
At any point, our table will have zebra-striped rows; we’ll use the :nth-child()
CSS pseudo-class to generate them.
On small and medium screens, the table header will be hidden. At this point, we’ll show a number indicating the movie number. We’ll replace the table headings with some strong
elements that will appear inside each cell.
So, on small screens, it will look like this:



On medium screens, the table will be a two-column grid:



On large screens, all table cells will have a width of 25%. Plus, the table headings will become visible.



Each time we hover over a row, an associated image will appear. Also, a small black bullet will sit at the center-right position to indicate the active row.



With all the above in mind, here’s a part of those styles. Notice how we begin with our table rows using display: flex; flex-wrap: wrap;
, with display: table-row;
kicking in once we hit the 1000px breakpoint:
/*CUSTOM VARIABLES HERE*/ table { margin: 50px 0 20px; text-align: left; border-collapse: collapse; border: 1px solid var(--table-border); } table th { color: var(--white); background: var(--darkblue); padding: 20px; } table td { width: 100%; padding: 10px; } table tbody tr { display: flex; flex-wrap: wrap; position: relative; counter-increment: counter; } table tbody tr::before { content: counter(counter); position: absolute; top: 20px; right: 20px; width: 30px; line-height: 30px; text-align: center; border-radius: 50%; font-weight: bold; color: var(--white); background: var(--black); z-index: 1; } table tbody tr:nth-of-type(even) > * { background: var(--lightblue); } table img { display: none; position: absolute; top: 20px; left: 45%; max-width: 150px; z-index: 1; } @media (min-width: 700px) and (max-width: 999px) { table tbody { display: flex; flex-wrap: wrap; } table tbody tr { width: 50%; } } @media (min-width: 1000px) { table th, table td { width: 25%; } table tbody tr { display: table-row; } } @media (hover: hover) and (min-width: 1000px) { table tbody tr:hover { cursor: pointer; } table tbody tr:hover img { display: block; } table tbody tr:hover td:first-child::before { display: block; } }
You can check them all by clicking on the CSS tab of the demo.
Conclusion
In this short tutorial, we covered a way to make a responsive table that will look great on different screens. On small and medium screens, we make it behave like a grid, whereas on larger screens, we have a typical table with cells.
Here’s a reminder of what we built:
As always, thanks a lot for reading!