No Time Dad

A blog about web development written by a busy dad

Creating and Styling a Simple Table with Tailwind

I don’t know why it hasn’t occurred to me to make a table with Tailwind until now. For my job, I make tables all the time. In fact, it’s one of the more common html elements I’ve made throughout my career. Tables aren’t the most exciting thing to make, but they’re the quickest and easiest way to display structured data on a page.

Table spacing has been notoriously difficult for me in the past. Especially headers. It’s even worse when the data is dynamic and I don’t always know how long a given header text is going to be. I’m hoping Tailwind will help with this, but given the fact that it’s mostly a wrapper on common css patterns I’m already familiar with, I’m not feeling optimistic.

I’ve come to terms with the fact that most tables just aren’t going to be responsive. Or I should say, they’re responsive to a certain point. The problem is that it’s hard to read tables on small screens. It’s just not a good user experience. In the past I’ve tried to force tables to be fully responsive, but it has almost always ended badly. I think I can live with a “mostly responsive” table.

Building the table

I’ll start by creating the table completely unstyled. The structure of the table isn’t going change, so I think it’s a good idea to just create a plain table first, then add the styles. For my example today, I’ll make a table with three columns and three rows. Below is the vanilla html version of the table without any Tailwind styles applied.

StageStatusDate
Pre-processDone5/28/2021
BuildDone5/28/2021
DeployFail5/28/2021
<table>
  <thead>
    <tr>
      <th>Stage</th>
      <th>Status</th>
      <th>Date</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Pre-process</td>
      <td>Done</td>
      <td>5/28/2021</td>
    </tr>
    <tr>
      <td>Build</td>
      <td>Done</td>
      <td>5/28/2021</td>
    </tr>
    <tr>
      <td>Deploy</td>
      <td>Fail</td>
      <td>5/28/2021</td>
    </tr>
  </tbody>
</table>
Styling the table element

So, there is my starting point. The table is small, though. I’d like it to be full width, and it’d also be nice if it stood out more from the background. I can do both of these things via Tailwind’s utility classes min-w-full for 100% width, and shadow-md to add a box-shadow, and rounded to round the corners. The latter styles basically turn the table into a card.

StageStatusDate
Pre-processDone5/28/2021
BuildDone5/28/2021
DeployFail5/28/2021
<table class="w-100 shadow-md rounded">
  ...
</table>
Styling the table header

The header row itself should differentiate itself from the rows beneath it. Basically, it should be a slightly different background color. To do this, I can apply Tailwind’s bg-gray-50 to the thead element. That way the entire header row will have the same background color in one shot.

For the table header th elements, I’ll add some padding as well as align the text to the left. I’ll use Tailwind’s p-4 utility class for the padding, and its text-left class for the text alignment. I think column titles should stand out more than the contents, so I’ll add font-bold to them too.

StageStatusDate
Pre-processDone5/28/2021
BuildDone5/28/2021
DeployFail5/28/2021
<table class="min-w-full shadow-md rounded">
  <thead class="bg-gray-50">
    <tr>
      <th class="p-4 text-left font-bold">Stage</th>
      <th class="p-4 text-left font-bold">Status</th>
      <th class="p-4 text-left font-bold">Date</th>
    </tr>
  </thead>
  <tbody>
    ...
  </tbody>
</table>
Styling the table body

The last part of the table I need to style now is the body. Which is also, in my opinion, the most important. The data in the table is what the users are here for.

I have two goals here. The first is that each row should have a bottom border border that helps with visual separation, making the data easier to read. The secon is that the data in a given column should line up with the column header.

Both of these goals are straightforward with css, and Tailwind makes them even easier. To the tbody tag I can add divide-y divide-gray-300 which will add the bottom border to each row. In the table data element (td) I’ll add padding: 1rem via Tailwind’s p-4 utility class, which matches the p-4 I applied to each table header (th) element. The matching padding will ensure that the data is aligned with the header.

StageStatusDate
Pre-processDone5/28/2021
BuildDone5/28/2021
DeployFail5/28/2021
<table class="min-w-full shadow-md rounded">
  <thead>
    ...
  </thead>
  <tbody class="divide-y divide-gray-300">
    <tr>
      <td class="p-4">Pre-process</td>
      <td class="p-4">Done</td>
      <td class="p-4">5/28/2021</td>
    </tr>
    <tr>
      <td class="p-4">Build</td>
      <td class="p-4">Done</td>
      <td class="p-4">5/28/2021</td>
    </tr>
    <tr>
      <td class="p-4">Deploy</td>
      <td class="p-4">Fail</td>
      <td class="p-4">5/28/2021</td>
    </tr>
  </tbody>
</table>

Conclusion & final code

This is not the most exciting table I’ve ever made, but it’s a good starting point to build on. Fancier data element styles could be added, the rows could be colored, the alignment could be changed, and so on. All of these things would are easier once I have a basic structure to work from, which is the point here.

Final code
<table class="min-w-full shadow-md rounded">
  <thead class="bg-gray-50">
    <tr>
      <th class="p-4 text-left font-bold">Stage</th>
      <th class="p-4 text-left font-bold">Status</th>
      <th class="p-4 text-left font-bold">Date</th>
    </tr>
  </thead>
  <tbody class="divide-y divide-gray-300">
    <tr>
      <td class="p-4">Pre-process</td>
      <td class="p-4">Done</td>
      <td class="p-4">5/28/2021</td>
    </tr>
    <tr>
      <td class="p-4">Build</td>
      <td class="p-4">Done</td>
      <td class="p-4">5/28/2021</td>
    </tr>
    <tr>
      <td class="p-4">Deploy</td>
      <td class="p-4">Fail</td>
      <td class="p-4">5/28/2021</td>
    </tr>
  </tbody>
</table>
StageStatusDate
Pre-processDone5/28/2021
BuildDone5/28/2021
DeployFail5/28/2021