Craft
Designing a Table Nobody Complains About
A table isn't a grid to dump rows into. The small calls in alignment and density make hundreds of numbers readable at a glance.
Tables rarely get designed. They get populated. Someone exports the data, drops it into a grid with a border around every cell, and moves on to the parts of the product that feel more interesting. Then the people who use the product every day spend hours squinting at it.
In many of the apps and dashboards we build, the table is the screen people look at most. It deserves at least as much care as the login page.
Start with what people do
Before choosing a single style, we find out what people use the table for. Are they scanning for one row? Comparing values down a column? Spotting the odd one out? Checking totals? Each task points to different priorities. A table for finding a customer by name needs a strong first column and good search. A table for comparing monthly figures needs numbers that line up perfectly.
Alignment does most of the work
The most useful rule is to align text to the left and numbers to the right. Right-aligned numbers put the units, tens and hundreds in the same place on every row, so the eye can compare sizes without reading each figure. Column headings follow the alignment of their content, so a numeric column has a right-aligned heading.
Tabular figures make a big difference here. In many typefaces, the digit 1 is narrower than the digit 8, so columns of numbers drift. Turning on tabular figures gives every digit the same width and keeps the columns straight. We also keep decimal places consistent within a column, so 12.5 and 12.50 never sit side by side.
Less decoration
Grid lines on every cell make a table look like a spreadsheet and make it harder to read. We usually remove vertical lines entirely and keep light horizontal dividers, or use subtle alternating row shading for very wide tables where it's easy to lose your place. The alignment of the columns creates the vertical structure on its own.
Colour is used sparingly. If every status is a coloured badge, the one that really matters doesn't stand out. We save strong colour for values that need attention, like overdue invoices or failed payments.
Choosing a density
There's no single right row height. People who live in a table all day often prefer a compact view that shows more rows at once. Occasional users prefer more spacing. In larger products, we sometimes offer both. When we can only choose one, we lean towards comfortable spacing for public-facing tables and compact for internal tools.
Headers that help
Column headings should be short and clear, with units in the heading rather than repeated in every cell. "Revenue (£k)" saves space and clutter. On long tables, the header row stays fixed as you scroll, so you never have to scroll back up to remember what a column means. The first column often stays fixed when scrolling sideways, for the same reason.
Sorting should be obvious. A small arrow shows which column is sorted and in which direction, and the whole heading is clickable, not just the arrow.
Tables on phones
Wide tables don't fit on narrow screens, and there's no perfect fix. Sometimes horizontal scrolling with a fixed first column works. Sometimes each row becomes a small card. Sometimes the mobile view shows fewer columns and lets people tap through to the detail. The right answer depends on the task, which is why we design the mobile table on purpose rather than letting it squash. It's a common conversation in our app development projects.
Empty, loading and long
Tables need states beyond "full of data". An empty table should explain why it's empty and what to do. A loading table should keep its shape so the page doesn't jump. A table with thousands of rows needs pagination or filtering that makes sense to the people using it.
Nobody will ever praise a well-designed table. They'll just get their work done faster and complain less. If your product has a table people grumble about, we'd like to hear about it.
Ready to talk about your project?
Start a conversation →