Free HTML Table Generator
Create HTML tables visually and copy the code.
How to Use
- Set the number of rows and columns, then click Apply.
- Type data directly into the editable table cells.
- Toggle options like header row, striped, bordered, and hover.
- Click Copy HTML to copy the generated code.
Frequently Asked Questions
Does the generated code include CSS?
Yes. When you enable options like striped, bordered, or hover, the tool generates inline CSS styles within the HTML so the table works anywhere.
What's the maximum table size?
Up to 50 rows and 20 columns. For larger datasets, consider using a spreadsheet tool and exporting to HTML.
How It Works
- Set table dimensions: Enter the number of rows and columns to generate the initial table grid.
- Fill in data: Click cells to enter content, add header rows, and toggle borders and striping.
- Style the table: Choose border style, header background color, row striping, and cell padding.
- Copy the HTML: The generated table markup includes a
<thead>with<th>headers and proper semantic structure.
Why Use HTML Table Generator?
Manually writing HTML table markup is tedious and repetitive, especially for tables with many rows or complex headers. Getting the correct nesting of <table>, <thead>, <tbody>, <tr>, <th>, and <td> elements right every time is error-prone. This generator produces semantically correct, accessible HTML tables with scope attributes on header cells for screen reader compatibility, proper caption support, and clean CSS for borders and hover states. Use it for pricing tables, comparison tables, data tables, and documentation.
Table Features
- thead/tbody structure: semantic table markup for accessibility
- Row striping: alternating row colors with nth-child CSS
- Border styles: full grid, horizontal only, or borderless
- Column span/merge: colspan and rowspan support
- Responsive wrapper: optional horizontal scroll wrapper for mobile
What is an HTML table generator?
An HTML table generator gives you a visual grid you can fill in like a spreadsheet, then emits the equivalent <table> markup with all the right semantic elements. Instead of typing <table>, <thead>, <tbody>, <tr>, <th> and <td> by hand and counting opening and closing tags, you set the dimensions, type the data, and copy the result. The output is HTML that validates and reads correctly to screen readers.
The semantic table elements have been in HTML since the 1993 draft and were formalized in HTML 2.0 (1995). They exist for one reason: tabular data. A pricing table, a comparison matrix, a sortable data grid, a periodic table of elements, any rectangular collection of facts where the rows and columns carry meaning. Tables read correctly to assistive technology when used for tabular data and create accessibility nightmares when used for page layout (the <div> and Flexbox era ended that abuse).
This generator outputs accessible markup with scope attributes on header cells, a separate <thead> for the header row, and inline CSS for the visual options you tick. The output is copy-paste ready for blog posts, documentation, email templates, and any context that accepts HTML. The visual grid runs entirely in your browser so no data leaves your device.
What is inside the generator
The top control row holds two number inputs (rows and columns), an Apply button, and four option checkboxes (header row, striped rows, bordered, hover effect). Adjust the dimensions first, click Apply, then tick the options that match your design. The editable grid below updates instantly, and the generated HTML in the textarea reflects every change you make.
The editable grid is a real HTML table with inputs in each cell, so you can tab between cells, paste a column of values, or use keyboard navigation. The header row (when ticked) renders with a colored background so you can tell at a glance which row will become <th> in the output. The output box below shows the resulting HTML in monospace, ready to copy.
Three action buttons sit at the bottom: Copy HTML writes the markup to your clipboard via the Clipboard API, Toggle Preview shows a rendered version below so you can confirm the styling, and Clear Cells empties the data without resetting the dimensions. The preview uses the same CSS as the output, so what you see is what your blog or doc will display.
History and background
Tim Berners-Lee proposes tables (1993)
The first HTML draft to include <table> was Dave Raggett's HTML 3.0 proposal in late 1993. The element was modeled on the LaTeX tabular environment and CALS table model used for technical documentation. Mosaic and early Netscape rendered tables as soon as the markup was proposed, even before standardization, which is why tables were one of the earliest visual primitives on the web.
RFC 1942 standardizes the table model (1996)
Dave Raggett's RFC 1942 (May 1996) gave HTML tables their first formal specification, including thead, tbody, tfoot, colgroup and the scope attribute for accessibility. The same year, the W3C HTML 3.2 recommendation adopted the table model essentially verbatim. The structure has remained largely unchanged for three decades.
The dark age of layout tables (1996 to 2005)
Before CSS was widely supported, designers used tables to position page elements: a four-cell table held the header, left nav, content and footer. The technique worked but produced unreadable markup, broke screen readers, and made redesign painful. Eric Meyer's CSS evangelism (2000-2005) and Jeffrey Zeldman's Designing With Web Standards (2003) ended the era, returning tables to their semantic purpose: tabular data.
CSS table-* display values (2004 onward)
CSS 2.1 added display: table, table-row and table-cell, so you could get table-like layout behavior on non-table elements. This was useful for the brief period when Flexbox and Grid were not yet supported (roughly 2010 to 2015). Today, display: grid and display: flex have replaced these CSS table values for layout, and real tables are reserved for data.
ARIA grid role and accessibility (2014)
WAI-ARIA 1.0 (2014) introduced role=grid for interactive tables and clarified how screen readers should announce table headers via the scope attribute and the headers/id pattern. Modern screen readers (NVDA, JAWS, VoiceOver) correctly read a properly-marked-up <table> with column and row context, which is impossible to replicate with <div>-based grids.
Responsive table patterns (2011 to present)
When the iPhone made small screens dominant, designers had to figure out how to show wide tables on narrow viewports. Filament Group's 2011 responsive tables article kicked off a wave of patterns: horizontal scroll, stacked rows on mobile, collapsing columns by priority. The CSS Working Group has been working on container queries and subgrid to make these patterns easier; for now, the standard approach is wrapping the table in overflow-x: auto.
Practical workflows
Pricing tables for a SaaS landing page
Three columns (Free, Pro, Enterprise) by ten or so feature rows. Tick header row to make the plan names <th> cells, tick bordered for clear separation, leave striped off if your design has its own row backgrounds. Copy the HTML, paste it into your CMS or static site, and add a thin wrapper class for theming.
Comparison matrix for blog reviews
When reviewing five tools across eight criteria, a table with striped rows and bordered cells reads more cleanly than a bulleted list. Tick striped, bordered and header row; type or paste the data; copy. The semantic markup makes the comparison readable in feed readers, archive services and screen readers.
Reference table in API documentation
API docs often show parameter name, type, default, and description in tabular form. The generator gives you the four columns with a header row, you fill in the parameters, copy the HTML and paste into Markdown that supports raw HTML, or into your docs framework (Docusaurus, MkDocs, Hugo). The scope attribute makes the columns navigable in screen readers.
Email newsletter (with caveat)
Email clients (Outlook 2007-2019 especially) have wildly inconsistent CSS support, so newsletter HTML still uses tables for layout (an exception to the no-layout-tables rule). For data tables inside a newsletter, the generator's inline-styled output works in most clients. Test in Litmus or Email on Acid before sending to a large list.
Internal dashboard quick mock
When prototyping an internal admin dashboard, a static HTML table with striped rows looks closer to the final product than placeholder text. Generate the structure, paste it into the React or Vue component, and replace the static data with a data-bound loop later.
PDF generation from HTML
When generating PDFs from HTML with tools like Puppeteer, wkhtmltopdf, or Chrome's print-to-PDF, tables render reliably across all engines. Use the generator to build the table, paste into your template, and run the PDF pipeline. The bordered option gives crisp printed lines without extra CSS.
Common pitfalls
Using tables for page layout
Tables are for tabular data, not page structure. A <table> with one row and three columns to position header, content and sidebar makes the page read as a data table to screen readers, which is confusing. Use Flexbox or CSS Grid for layout instead. The only exception is HTML email, where layout tables are still necessary for cross-client rendering.
Missing scope attribute on header cells
Each <th> should have scope="col" or scope="row" so screen readers know which header applies to which data cell. Without scope, the reader has to guess, often producing wrong context. This generator emits scope automatically for header rows. If you edit the HTML manually, keep scope attributes in place.
Complex headers (multi-level) without headers/id
Tables with grouped column headers (Q1, Q2 each split into Jan, Feb, Mar) need the headers attribute on each data cell pointing to the id of the relevant headers. Scope alone is insufficient for two-level headers. The generator does not produce complex headers; for these, edit the HTML manually or use a CMS plugin that supports the pattern.
Wide tables on mobile
A six-column table is unreadable on a 375-pixel-wide phone screen. The default mobile-friendly pattern is to wrap the table in a div with overflow-x: auto so the user can scroll horizontally. For column-heavy tables, consider stacking the rows into mini-cards on small screens via @media (max-width). The generator output is not auto-wrapped; add the wrapper in your CSS.
Empty cells without explicit content
A blank <td></td> reads as empty to screen readers, which sounds odd when listing 50 entries. If a cell legitimately has no data, write <td>—</td> or <td aria-label="no data">–</td>. Mind that the dash entity introduces an em-dash, which this site avoids; use a hyphen, "N/A", or "Not available" instead.
Sorting and filtering without progressive enhancement
A static HTML table cannot be sorted or filtered by users. If your audience needs interactivity, layer in DataTables, AG Grid, or Tanstack Table. The generator produces the underlying semantic table, which becomes the foundation for these libraries. Keyboard navigation and ARIA roles come with the library.
Privacy and data handling
Everything runs in your browser. The visual grid, the HTML output, and the preview all live in client-side JavaScript. We do not send your data anywhere, log inputs, or store anything in cookies or localStorage. Reload the page and the previous table is gone.
Once the page is loaded, the tool works offline. You can disconnect from the network and build tables containing customer data, internal pricing, or any other confidential content without it touching a third-party server. The Copy HTML button uses the Clipboard API which requires a user gesture and is not observable to external parties.
When not to use a static HTML table
Page layout (use Flexbox or Grid)
If you want a sidebar next to main content, a card grid, or a navigation bar, use CSS Flexbox (display: flex) or CSS Grid (display: grid). Tables for layout produce confusing screen reader output and inflexible HTML that does not adapt to viewport changes the way modern layout primitives do.
Large datasets (above 1000 rows)
A 10,000-row static HTML table is slow to render and consumes significant memory. Use a virtualizing grid library (TanStack Virtual, React Window, AG Grid) that only renders visible rows. Static HTML is fine for under a few hundred rows.
Interactive data manipulation (use a grid library)
When users need to sort, filter, edit, group or paginate, you need a real grid library. AG Grid, TanStack Table, DataTables, and Bootstrap Table all produce accessible <table> markup under the hood while adding interactivity. The generator's output is the starting point, not the finish.
Charts and graphs (use SVG or canvas)
A bar chart is not a table, it is a visualization. Use Chart.js, D3, Recharts, or any SVG-based charting library. If you need both a chart and a backing data table for accessibility, render the chart and place an <table> with the same data nearby (or hidden in a visually-hidden class) so screen reader users get the numbers.
More questions
Should I always use thead and tbody?
For tables with a header row, yes. <thead> separates the header rows from the data rows, which lets browsers freeze the header on long tables and lets screen readers announce headers correctly. The generator includes thead automatically when the header row option is ticked. For tables without a header, you can omit both, but it is cheap to include <tbody> for completeness.
When do I use scope="col" vs scope="row"?
scope="col" goes on <th> cells that label a column (the top row of headers). scope="row" goes on <th> cells that label a row (the leftmost cell when each row has a name). Most tables have only column headers, so scope="col" is the common case. If you have both, mark each with the appropriate scope.
How do I make a sortable table?
Use a JavaScript library that adds click-to-sort to existing <table> markup. Sortable.js, TanStack Table, and DataTables all do this. Pure CSS cannot sort. The generator's output is the static foundation; layer the library on top in your final project. For accessibility, the library should add aria-sort to the active column.
What is the best responsive pattern?
The simplest and most accessible is overflow-x: auto on a wrapping div, which preserves the table's semantics while letting users scroll horizontally. For column-heavy tables, the stacked-row pattern (display: block on tds at narrow widths, with data labels via data-label attributes) reads each row as a labeled list on mobile. Both are valid; pick based on the table's read-vs-compare use case.
Can I use HTML tables in Markdown?
Most Markdown processors (GitHub Flavored Markdown, Pandoc, MDX, MkDocs, Hugo) accept raw HTML alongside Markdown syntax, so you can paste the generator's output directly. Markdown's native table syntax is simpler but lacks colspan, rowspan, scope and styling, so for anything beyond a simple grid, HTML is better. Note: some strict Markdown parsers (CommonMark without extensions) ignore HTML by default.
How do I style alternating row colors without CSS?
Tick the Striped Rows option in the generator. The output includes inline style attributes on every other row, so the striping survives even in contexts where CSS is stripped (some webmail clients). If your environment allows external CSS, prefer tr:nth-child(even) in a stylesheet, which is cleaner than inline styles and easier to update.