HTML table generator

Build clean, semantic table markup with accessible headers and a live preview — plus a starter stylesheet to make it look right.

HTML Table Generator

Build clean, semantic table markup — with a proper header row and accessible scope attributes — plus a starter stylesheet to make it look right.

Live Preview (markup + starter CSS, as it renders on a plain page)

Copy-Paste Output

HTML markup
Starter CSS

Semantic Tables Still Matter

Screen readers navigate tables by their structure: <thead>, <th scope="col"> and <tbody> tell assistive technology which cell is a label and which is data, so users can hear “Header 2: Row 3 value” instead of a wall of unlabelled numbers. Div-grids styled to look like tables lose all of that for no gain.

The old sin was using tables for page layout; the modern mistake is the reverse — avoiding tables for actual tabular data. If the content is rows and columns of related values, a real <table> is the correct, accessible and SEO-friendly element. Google can parse well-structured tables into rich results, and your keyboard users get row-by-row navigation for free.

Why table structure matters for accessibility

Sighted readers understand a table instantly because they can see the grid. Screen reader users can't — they navigate cell by cell, and rely entirely on the markup to know what each value means.

That's what <thead>, <th> and the scope attribute provide. With them, moving through a table announces "Revenue, Q3: £48,000" — the header travels with the value. Without them, it announces "48,000" and the user has to remember which column they're in. On a wide table, that's the difference between usable and useless.

scope="col" marks a header for its column; scope="row" marks one for its row. Adding a <caption> is worth doing too — it gives the whole table a title that assistive technology announces on entry.

The layout-tables myth, and its modern inversion

In the 1990s, tables were the only reliable way to build page layouts, and the practice persisted long after CSS could do the job properly. The correction — "never use tables" — became received wisdom.

It over-corrected. The rule was always don't use tables for layout, not don't use tables. Today the more common mistake is the reverse: building tabular data out of divs and flexbox because tables feel outdated. That throws away every accessibility benefit above, plus keyboard navigation and the browser's own column alignment, and gains nothing — CSS can style a real <table> however you like.

The test is simple: if your content is rows and columns of related values, it is a table. Use one.

Making tables work on mobile

Wide tables are the genuine hard problem in responsive design. Three approaches work, depending on the data.

Horizontal scroll is the simplest and safest: wrap the table in a container with overflow-x: auto, keeping the structure intact. Add tabindex="0" to that wrapper so keyboard users can scroll it too — an easily missed accessibility detail. Stacked cards re-flow each row into a block with labels shown inline, which reads well on phones but needs the labels duplicating in CSS or data attributes. Column hiding shows only essential columns on narrow screens, which works when some columns are genuinely secondary.

Styling that aids comprehension

A few choices measurably improve how quickly people read a table. Zebra striping helps the eye track across long rows. Right-aligning numeric columns lines up the digits so magnitudes are comparable at a glance — a detail that separates a considered table from a default one. Generous cell padding beats tight borders for readability, and a sticky header row keeps context visible while scrolling long data sets.

Frequently asked questions

Is it bad practice to use HTML tables?

Only for page layout. For genuine tabular data — rows and columns of related values — a real table element is the correct, accessible and SEO-friendly choice. Building tables out of divs discards accessibility for no benefit.

What does scope="col" do in a table?

It tells assistive technology that a th cell is the header for its column, so screen readers announce the header alongside each value — "Revenue, Q3: £48,000" instead of an unlabelled number. Use scope="row" for row headers.

How do I make an HTML table responsive?

The simplest reliable method is wrapping it in a container with overflow-x: auto so it scrolls horizontally with its structure intact. Add tabindex="0" to that wrapper so keyboard users can scroll it as well.

Should I add a caption to my table?

Yes where the table needs a title. A caption element gives the table an accessible name that screen readers announce on entry, providing context before the user starts navigating cells.