Responsive tables on mobile screens

Constantin Druc ยท 14 Dec, 2021

[00:00] We have a table representing some orders. We have columns like number, details, status, and so on. Let's start by making this table look really nice, and then we'll see what options we have for smaller screens.

[00:21] Our viewport is not even that small and the table already looks messed up. First, let's make the table full width, and then style the head. We'll do bg gray-50 for background and border-b-2 border-gray-200 to have like a thick border separating the headings from the table rows. Next up, let's focus on the table headings themselves.

[00:45] We'll do p-3 for padding, text-sm font-semibold tracking-wide to make the text more legible, and then text left. Moving on to the rows, let's make this a striped table, so odd and even rows will have a different background color - this makes it easier to follow a particular row once you set your eyes on it.

[01:07] Since our table head background is gray, we'll do white for the first row. Then we'll do gray, white again and so on. Now for the cells, let's first select all the td elements, and then do class p-3 for padding, and then text-sm text-gray-700. Apart from this, I also want to style the links for the order numbers. So let's do that.

[01:39] So let's do that. I'll select all the links and do class font-bold text-blue-500, and then on hover we'll do hover:underline, and here they are. Now here, this ship status will look better as a badge. So let's wrap it within a span and do p-1.5 text-xs font-medium uppercase tracking-wider text-yellow-800 bg-yellow-200 and then let's round it using rounded-lg, and let's reduce the background opacity using bg-opacity-40.

[03:18] If we look at the table in a larger window, we'll see that the order number, status, date, and total, take up unnecessary space. We could set some sensible widths for these columns. We'll go here to our headings and say w-20 for the order number, w-24 for the status and for the date, and then w-32 for the total.

[03:52] And here it is. Now we have more space for the details column. Before getting into the responsive part, I want to do one more thing, and that's adding borders for our rows. And we can do that by going to the table body, add class divide-y, and then to set the color, we can use divide-gray-100.

[04:19] Now for mobile screens, we have two options. The first one allows the table to stretch on the horizontal axis as much as it needs, but of course, we need to do that without ruining the design. To start, we'll need to prevent the column text from wrapping. So let's select all the table columns, and then add the whitespace-nowrap class. So now every table cell takes as much space as it needs.

[04:45] But if I scroll to the left, we'll see that our layout is broken. To fix this, we can wrap our table within a div. So let's do that. We'll do div and then add the overflow-auto class. And to make this look even nicer, we can add rounded-lg and a shadow. And now if I go into a browser and scroll, the scroll works, but our layout is no longer broken.

[05:16] Let's also check this on a larger screen, and here it is. Personally, I quite enjoy this option, but I've met people who aren't that fond of it. So let's move on to the second option, which is.... just hide the table on small screens and show a grid instead. I know this looks a bit awful as we end up with a lot of code, but if we were to use a loop in blade or vue, it wouldn't look nearly as bad.

[05:49] So let's hide this on small screens. We'll do hidden, and then on md:block we'll do block. This will hide the table on small screens and show it on larger ones. Moving on, let's add our mobile only grid. We'll do div.grid.grid-cols-1.gap-4.md:hidden. Now for the items, we'll have a wrapper and then one container to hold the order number, one for the date, and another one for the status. We'll then have the description and the total.

[06:37] Now let's style these. We'll start with the wrapper. We'll do bg-white p-4 rounded-lg shadow. Now for these elements, we'll do a flex items-center, add some margin using space-x-2, and then text-sm.

[07:03] For the order number, we'll have a link, and let's say text-blue-500 font-bold hover:underline. Now for the date, we'll just say text-gray-500, for the status I'll just copy the badge. So let's grab this one. Let's also copy the description, and here I'll do text-sm text-gray-700, then for the total we'll do text-sm font-medium text-left.

[08:06] Now these look a bit crammed up, so let's add some spacing between them. And we can do that by going to the wrapper and say space-y-3. Let's add the remaining orders, and I'll just duplicate this one and replace the order number and status. For the status, we'll do "Shipped", and this has yellow instead of green, and then we'll do "Cancelled", and this one is gray.

[08:47] Then on sm we could display two columns instead. So we could do sm:grid-cols-2, and this is a bit better. Let's view it in a larger browser - so this will be our mobile screen, and as it gets bigger, it will transition to two columns, and then finally, into a table.

[09:40] And that's it. That's how I can deal with tables on mobile devices.