HTML Table Generator
Build HTML tables visually — edit cells inline, choose a style, copy clean HTML code
Table Style
Indentation
Header Row
Include CSS
Table Editor (3 × 3)
Click any cell to edit its content. Use the × buttons to remove rows or columns. Max 50 rows × 20 columns.
You need a 5-column comparison table for your pricing page. Hand-coding <table>, <thead>, <tbody>, <tr>, <th>, and <td> with colspan and styles means 60+ lines of HTML for a simple table — and one missing </tr> breaks the entire layout. Then you need striped rows, hover highlighting, and a header row with a different background. You know the HTML, you just don’t want to type it.
Why This Generator (Not a Markdown Table)
Markdown tables are simple but can’t do merged cells, inline styles, or header groups. This visual editor lets you set rows and columns, edit cells inline, toggle header rows, apply styles (bordered, striped, hover), and copy clean HTML with optional inline CSS. Everything runs in your browser; no data is sent anywhere.
What Is an HTML Table?
An HTML table organizes data into rows and columns using the <table>, <thead>, <tbody>, <tr>, <th>, and <td> elements. Tables are ideal for displaying structured data — pricing plans, comparison charts, schedules, and data grids — where the relationship between rows and columns is meaningful.
Basic table anatomy:
<table>
<thead>
<tr>
<th>Name</th>
<th>Role</th>
<th>Department</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alice</td>
<td>Engineer</td>
<td>Platform</td>
</tr>
<tr>
<td>Bob</td>
<td>Designer</td>
<td>Product</td>
</tr>
</tbody>
</table>
When to Use HTML Tables
Use <table> when the data is genuinely tabular — when rows and columns both carry meaning:
| Use Case | Use Table? |
|---|---|
| Product comparison (features vs. plans) | Yes |
| Sports league standings | Yes |
| Financial data with totals | Yes |
| Page layout / multi-column design | No — use CSS Grid or Flexbox |
| Navigation menus | No — use <nav> and <ul> |
| Form layout | No — use CSS Grid |
Tables are also accessible: screen readers announce row and column headers automatically when <th> elements and proper scope attributes are used.
HTML Table Elements Reference
Core Structure
| Element | Purpose |
|---|---|
<table> | Root element wrapping the entire table |
<thead> | Groups header rows (rendered at the top, repeated on print) |
<tbody> | Groups body rows (the data) |
<tfoot> | Groups footer rows (totals, summaries) |
<tr> | Table row — container for cells |
<th> | Header cell — bold, centered by default; associates with row or column |
<td> | Data cell — standard table cell |
Useful Attributes
| Attribute | Element | Purpose |
|---|---|---|
colspan | <td>, <th> | Span multiple columns: <td colspan="2"> |
rowspan | <td>, <th> | Span multiple rows: <td rowspan="3"> |
scope | <th> | Accessibility — scope="col" or scope="row" |
headers | <td> | Link a cell to its header IDs for complex tables |
caption | <caption> | Table title (placed as first child of <table>) |
Table Styling Approaches
1. Plain (No Extra Styles)
A bare table with no CSS inherits browser defaults — no borders, compact appearance:
<table>
<thead><tr><th>Name</th><th>Score</th></tr></thead>
<tbody><tr><td>Alice</td><td>95</td></tr></tbody>
</table>
Best when you apply your own design system styles.
2. Bordered
Adds a 1px border to the table and every cell:
.html-table,
.html-table th,
.html-table td {
border: 1px solid #d1d5db;
}
.html-table {
border-collapse: collapse;
}
border-collapse: collapse merges adjacent borders into a single line, avoiding doubled borders between cells.
3. Striped (Zebra Rows)
Alternating background on even rows improves readability for wide tables:
.html-table tbody tr:nth-child(even) {
background-color: #f9fafb;
}
The :nth-child(even) selector targets every second row. Use odd to shade the first row instead.
4. Hover Highlight
Highlights the row the user hovers over — helps track across wide tables:
.html-table tbody tr:hover {
background-color: #eff6ff;
}
Combine with striped for a striped-hover effect that remains readable.
Accessibility Best Practices
Use <th> for Headers
Always mark header cells with <th> instead of <td>:
<tr>
<th scope="col">Product</th>
<th scope="col">Price</th>
<th scope="col">Stock</th>
</tr>
The scope="col" attribute tells screen readers this header applies to the entire column.
Add a Caption
Describe the table’s purpose with <caption>:
<table>
<caption>Q3 2024 Sales by Region</caption>
<thead>...</thead>
<tbody>...</tbody>
</table>
The caption appears visually above the table and is announced by screen readers before the data.
Row Headers
For tables with row labels, mark the first cell as a row header:
<tr>
<th scope="row">North America</th>
<td>$1.2M</td>
<td>$0.9M</td>
</tr>
Avoid Layout Tables
Screen readers announce the presence of a table and navigate it with special commands. Using tables for visual layout creates a confusing experience for assistive technology users. Use CSS Grid or Flexbox for page layout instead.
Responsive Tables
HTML tables do not reflow on small screens. Common approaches:
Horizontal Scroll Wrapper
<div style="overflow-x: auto;">
<table class="html-table">...</table>
</div>
The simplest solution — the table scrolls horizontally on narrow viewports.
CSS Stacked Rows (Mobile)
@media (max-width: 640px) {
.html-table thead { display: none; }
.html-table td {
display: block;
text-align: right;
}
.html-table td::before {
content: attr(data-label);
float: left;
font-weight: 600;
}
}
Each row becomes a card on mobile, with data-label providing the column name context.
Column Widths and Layout
By default the browser auto-sizes columns based on content. Control widths with CSS:
/* Fixed-layout mode — column widths set by first row */
.html-table {
table-layout: fixed;
width: 100%;
}
/* Explicit column widths */
.html-table th:nth-child(1) { width: 40%; }
.html-table th:nth-child(2) { width: 30%; }
.html-table th:nth-child(3) { width: 30%; }
table-layout: fixed gives consistent column widths and improves performance for large tables.
Spanning Cells
Column Span
<tr>
<th colspan="2">Full Name</th>
<th>Score</th>
</tr>
<tr>
<td>First</td>
<td>Last</td>
<td>98</td>
</tr>
Row Span
<tr>
<td rowspan="2">Alice</td>
<td>January</td>
<td>$4,200</td>
</tr>
<tr>
<td>February</td>
<td>$3,800</td>
</tr>
Frequently Asked Questions
Should I include <thead> and <tbody> in every table?
Technically they are optional — the browser adds them implicitly. But including them explicitly improves readability, enables separate styling of header vs body rows with CSS selectors, and helps screen readers identify the header area.
What does border-collapse: collapse do?
By default (border-collapse: separate), each cell has its own border, resulting in doubled lines between adjacent cells. collapse merges adjacent borders into a single shared border, which is almost always what you want.
How do I sort table rows with JavaScript?
Collect the <tr> elements from <tbody> into an array, sort by the text content of the desired column’s <td>, then re-append the sorted rows to <tbody>. No library needed for simple alphabetical or numeric sorting.
Is there a maximum number of rows or columns? The HTML specification has no limit. Performance degrades in the browser DOM above roughly 10,000 cells; for large datasets use virtual scrolling or paginate the data.
When should I use <th scope="colgroup"> or <colgroup>?
For complex tables with merged column headers spanning multiple columns, scope="colgroup" on the spanning header plus <colgroup> and <col> elements improve accessibility by correctly associating header cells with their data columns.
Does this tool send my data to a server? No. All table generation and HTML output happens in your browser. Nothing is uploaded or transmitted.