Tailwind Tables and Lists
Tables present data in rows and columns. Lists present items in a sequence. Browsers style both with plain defaults, and Preflight removes even those. Tailwind classes rebuild clean, readable versions with only a few utilities per element.
Building a Basic Table
Start with a full-width table, collapse the borders, and align text to the left. Add padding to every cell so the data can breathe.
<table class="w-full border-collapse text-left text-sm">
<caption class="p-2 text-left font-bold">Topic list</caption>
<thead class="bg-gray-100">
<tr>
<th scope="col" class="p-3">Name</th>
<th scope="col" class="p-3">Level</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr><td class="p-3">Flexbox</td><td class="p-3">Beginner</td></tr>
<tr><td class="p-3">Container Queries</td><td class="p-3">Advanced</td></tr>
</tbody>
</table>
Name Level
─────────────────────────────
Flexbox Beginner
─────────────────────────────
Container Queries Advanced
The divide-y class draws a line between rows, so no border classes appear on each row. The scope attribute and the caption tell screen readers how the table is organized.
Striped Rows and Hover Highlights
<tr class="odd:bg-white even:bg-gray-50 hover:bg-sky-50">
Alternating colors guide the eye across wide rows. A hover color shows which row the pointer rests on.
Scrolling Wide Tables
A table with many columns overflows a phone screen. Wrap it in a container that scrolls sideways. The page stays fixed while the table moves.
<div class="overflow-x-auto">
<table class="min-w-full">...</table>
</div>
Phone screen
┌────────────────┐
│ Name Level Pr│→ swipe sideways to see more
└────────────────┘
Sticky Header
Long tables lose their column names as the reader scrolls down. Fix the header in place with sticky positioning and a background color, so the text underneath stays hidden.
<thead class="sticky top-0 bg-white shadow-sm">
Table Layout Helpers
Class Effect
────────────────────────────────────────────
table-auto columns fit their content (default)
table-fixed equal widths unless you set them
border-collapse merges neighboring borders
border-spacing-2 adds gaps between cells
tabular-nums numbers line up in columns
text-right right-aligns number columns
Styling Lists
Preflight removes bullets and numbers. Bring them back with list classes. The list-inside class places markers within the text block, and the default list-outside hangs them in the margin.
<ul class="list-disc space-y-1 pl-6 marker:text-sky-500">
<li>Install Tailwind</li>
<li>Write utility classes</li>
</ul>
• Install Tailwind (sky blue bullets)
• Write utility classes
list-disc • filled bullet
list-decimal 1. 2. 3.
list-none no markers
Interface Style Lists
Many interfaces use lists without markers, such as contact lists and settings menus. Each item becomes a flex row.
<ul class="divide-y divide-gray-200">
<li class="flex items-center gap-3 py-3">
<img class="h-10 w-10 rounded-full" src="user.jpg" alt="Maria">
<div>
<p class="font-medium">Maria</p>
<p class="text-sm text-gray-500">Designer</p>
</div>
</li>
</ul>
Spacing and Readability in Tables
Cell padding controls how dense a table feels. A value of p-2 suits compact data screens, and p-4 suits relaxed reading. Pick one value and apply it to every header and data cell, so columns align cleanly. Soft borders in gray-200 separate rows without shouting. Heavy black lines on every cell look cluttered and slow the eye.
Header text deserves a different weight from body text. Add font-semibold and a slightly darker color to header cells. Small uppercase labels with text-xs uppercase tracking-wide give a modern dashboard look. Keep the header background light so the data stays the focus.
Nested and Description Lists
Nested lists show hierarchy. Add left padding to the inner list and switch its marker style, such as list-disc outside and list-[circle] inside, to signal the new level. A description list pairs a term with its meaning and suits settings pages and profile details.
<dl class="divide-y">
<div class="flex justify-between py-2">
<dt class="text-gray-500">Plan</dt>
<dd class="font-medium">Free</dd>
</div>
</dl>
Choosing Between a Table and a List
Use a table when each item has several attributes that readers compare across rows, such as prices, dates, and names. Use a list when items stand alone or carry one main idea. Grid layouts built with divs look like tables but lose the structure that assistive tools read, so choose real table tags for real tabular data.
Mobile Friendly Alternatives
Narrow screens struggle with many columns. Two approaches help. Hide minor columns with hidden md:table-cell, so phones see only the essentials. Switch the layout to stacked cards below a breakpoint, with each row turning into a small block of label and value pairs.
- Keep column headings short, so they fit above narrow data.
- Align numbers to the right and use
tabular-numsfor neat digits. - Test with a screen reader or browser accessibility panel to confirm headings connect to cells.
Clean tables and lists make information easy to scan, and Tailwind keeps their styling inside the markup.
