Clean, semantic HTML tables without typing tags
Writing an HTML table by hand means a lot of tags: a tr for every row, a td for every cell, and the parts that make a table accessible are easy to forget. This HTML table generator gives you a grid like a small spreadsheet. You type or paste the data, choose which row and column hold the headers, and it writes the table code with thead, tbody, header cells with the right scope, an optional caption and footer, and minimal CSS if you want it. Every character in your cells is escaped, and a sandboxed preview shows the result.
The grid is the same one as in the Markdown table generator, so you can paste cells from Excel or Google Sheets, import CSV or a Markdown table, and move rows and columns around. For other markup tasks, the HTML entity converter encodes special characters, the Markdown to HTML converter turns whole documents into HTML, and the CSS and JS minifier shrinks the CSS for production.
The parts of an HTML table
The HTML standard (section 4.9, tabular data) sets the order of the parts inside a table: first an optional caption, then column groups, then an optional thead, then the body rows, and an optional tfoot at the end. The generator writes them in that order:
| Element | What it is | When the generator writes it |
|---|---|---|
| <caption> | The title of the table, its first child | When you type a caption |
| <thead> | The rows with the column headers | First row is the header |
| <tbody> | The data rows | Always, when there are data rows |
| <tfoot> | Summary rows, such as totals | Last row is a footer |
| <th scope="col"> | A header for the cells below it | Cells of the header row |
| <th scope="row"> | A header for the cells to its right | First cell of each row, when the first column holds row headers |
| <td> | A data cell | All other cells |
The standard is also clear about what tables are not for: tables must not be used as layout aids. Use them for data with rows and columns, and CSS grid or flexbox to lay out a page. The align attribute on cells is obsolete in the standard, so the generator sets alignment with a text-align style instead.
Make the table accessible
The W3C Web Accessibility Initiative tables tutorial explains why header markup matters: screen readers use it to announce the row and column headers as people move through the cells, which visual styling alone cannot do. Its advice, and how the generator follows it:
- Header cells are th, data cells are td. The header row always uses th. Turn on First column holds row headers when the first column names each row, like a region or a product.
- Give headers a direction. For tables with a header row and a header column, the two headers tutorial uses scope="col" and scope="row". The generator adds both.
- Add a caption. The caption tutorial says a caption works like a heading for the table and is often needed.
- Keep tables simple. The tips page suggests splitting a complex table into simpler ones, and starting a new table when the topic changes instead of adding a second header row.
- Align with care. The same page suggests aligning text left and numbers right in left-to-right languages, with each header aligned like its data. Set this per column in the menus at the top of the grid.
- Do not cut off wide tables. Tables that are too wide should not be clipped. The tips wrap them in an element that scrolls, which is what Scroll box for narrow screens does.
Tables with cells that span several rows or columns, or with headers on several levels, need id and headers attributes, which the tutorial covers. The generator makes simple grids without merged cells, so scope is all they need.
Worked example
A small sales table: the first row names the quarters, the first column names the regions, and the last row holds the totals. The caption is Orders by region, the number columns are aligned right, and First column holds row headers and Last row is a footer are on. Press Fill in an example to load it. Without CSS, the generator writes:
<table class="data-table">
<caption>Orders by region</caption>
<thead>
<tr>
<th scope="col">Region</th>
<th scope="col" style="text-align: right">Q1</th>
<th scope="col" style="text-align: right">Q2</th>
<th scope="col" style="text-align: right">Total</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">North</th>
<td style="text-align: right">120</td>
<td style="text-align: right">135</td>
<td style="text-align: right">255</td>
</tr>
<tr>
<th scope="row">South</th>
<td style="text-align: right">98</td>
<td style="text-align: right">110</td>
<td style="text-align: right">208</td>
</tr>
</tbody>
<tfoot>
<tr>
<th scope="row">Total</th>
<td style="text-align: right">218</td>
<td style="text-align: right">245</td>
<td style="text-align: right">463</td>
</tr>
</tfoot>
</table> Each number in the body is announced with its region and its quarter, the totals sit in a tfoot after the body, and the alignment uses a style, not the obsolete align attribute.
The CSS options
Add minimal CSS puts a short style block before the table, written for the class name you choose, so it does not change other tables on your page. It collapses the borders, adds padding and aligns cells left and to the top, with a line under the header. On top of that you can switch on:
- Striped rows: a light gray background on every second body row. The W3C tips note that alternating rows can help people with reading difficulties or who enlarge the text.
- Borders around cells: a thin border on every cell and a gray header row instead of the lines between rows.
- Compact padding: half the padding, for tables with many rows.
- Scroll box for narrow screens: a div with overflow-x: auto around the table, with role="region", the caption as its label and tabindex="0", so it can also be scrolled with the keyboard.
Last row is a footer adds a heavier line and bold text to the tfoot. The CSS sets no text color, so the text keeps the color of your page. The lines and row backgrounds are light grays made for a light background; change them to match your site after you paste the code.
Escaping and line breaks
Everything you type is text, never markup. The generator replaces &, <, > and " with &, <, > and ", so a cell like <script> shows those characters on the page and cannot run. A line break in a cell, made with Shift+Enter, becomes a <br> tag. The class name is checked too: it may only hold letters, digits, hyphens and underscores, and must not start with a digit.
How to use the HTML table generator
- 1Type into the grid, paste cells from a spreadsheet into a cell, or open Import data and paste CSV, a Markdown table or an existing HTML table.
- 2Add a caption, then choose whether the first row, the first column and the last row are headers or a footer.
- 3Set the alignment of each column at the top of the grid and pick the CSS options you want.
- 4Check the preview, then copy the HTML or download it as a file.
Sources
- WHATWG HTML Living Standard: 4.9 Tabular data (table content model, caption, th and scope)
- WHATWG HTML Living Standard: 16 Obsolete features (align on td and th)
- W3C WAI: Tables Tutorial
- W3C WAI: Tables with two headers
- W3C WAI: Caption and summary
- W3C WAI: Tables tips and tricks
Frequently asked questions
What is the difference between th and td?
A th element is a header cell and a td element is a data cell. The W3C accessibility tutorial asks for th on every header, because screen readers use it to announce the matching row and column header as people move through the cells. The generator writes th for the header row and, when you turn it on, for the first cell of every row.
What does scope="col" and scope="row" do?
It tells software which cells a header belongs to. In the HTML standard, scope="col" makes a header apply to the cells below it in its column and scope="row" to the cells after it in its row. The W3C tutorial uses both in tables that have a header row and a header column, which is the case the generator covers.
Should my table have a caption?
Usually yes. The W3C tutorial says a caption works like a heading for the table and helps people find it and decide whether to read it. Type the caption above the options and the generator puts it in a caption element, the first child of the table, as the HTML standard requires.
Why does the code use style="text-align: right" and not align="right"?
The align attribute on td and th is listed as obsolete in the HTML standard and must not be used. A text-align style does the same and works with any CSS. The W3C tips suggest aligning text left and numbers right, and aligning each header with its data.
How do I make the table work on phones?
Turn on Scroll box for narrow screens. The table is then wrapped in a box that scrolls sideways when the table is wider than the screen, so no column is cut off. The W3C tips warn against hiding the overflow of wide tables and wrap them in a scrolling element instead.
Is the text in my cells escaped?
Yes. The characters &, <, > and " become &, <, > and ", so text like <b> shows as text and cannot add markup or scripts to your page. A line break inside a cell becomes a <br> tag.
Is my data uploaded?
No. The grid, the code and the preview are all made in your browser. Copy link only shares your settings, not the table.