The <table> tag is the fundamental element for creating data tables in HTML. Whether you want to display statistics, compare products, or present structured information, HTML tables remain an essential tool in modern web development.
If you're just starting with HTML and want to master table creation along with other essential elements, our HTML course will guide you step by step through your learning journey.
HTML tables are designed for displaying tabular data, not for page layout! Use CSS Grid or Flexbox for your page layouts 😊
Definition and syntax of the table tag
What is the table tag?
The <table> tag defines a table in HTML. It serves as the main container for organizing data into rows and columns. A well-structured table improves the readability of your information and makes it easier for users and search engines to understand.
A complete HTML table consists of several elements working together:
<table>: the main table container<thead>: the table header (optional but recommended)<tbody>: the table body containing the data<tfoot>: the table footer (optional)<tr>: a table row<th>: a header cell (table header)<td>: a data cell (table data)
Basic syntax
Here is the minimal structure of an HTML table:
<table>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
<tr>
<td>Data 1</td>
<td>Data 2</td>
</tr>
</table>This structure creates a simple table with one header row and one data row.
Recommended complete structure
For a semantically correct and accessible table, we recommend using grouping elements:
<table>
<caption>Believemy Course List</caption>
<thead>
<tr>
<th scope="col">Course</th>
<th scope="col">Duration</th>
<th scope="col">Level</th>
</tr>
</thead>
<tbody>
<tr>
<td>HTML & CSS</td>
<td>20 hours</td>
<td>Beginner</td>
</tr>
<tr>
<td>JavaScript</td>
<td>35 hours</td>
<td>Intermediate</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">Total</td>
<td>2 courses</td>
</tr>
</tfoot>
</table>The <caption> element provides a descriptive title for the table, which is essential for accessibility.
Attributes of the table tag
Global attributes
The <table> tag accepts all global HTML attributes, including:
| Attribute | Description | Example |
|---|---|---|
id | Unique identifier for the table | id="courses-table" |
class | CSS classes for styling | class="table-responsive" |
style | Inline CSS styles | style="width: 100%;" |
title | Tooltip on hover | title="2024 Data" |
Deprecated attributes to avoid
Some attributes were used in older versions of HTML but are now deprecated:
The attributes border, cellpadding, cellspacing, width, bgcolor, and align are deprecated. Use CSS to style your tables!
Here's how to replace these old attributes with modern CSS:
/* Replaces border="1" */
table {
border-collapse: collapse;
}
table, th, td {
border: 1px solid #333;
}
/* Replaces cellpadding="10" */
th, td {
padding: 10px;
}
/* Replaces cellspacing="0" */
table {
border-spacing: 0;
}
/* Replaces width="100%" */
table {
width: 100%;
}
/* Replaces bgcolor */
table {
background-color: #f5f5f5;
}
Practical examples of HTML tables
Simple data table
Let's start with a concrete example: a table listing learners and their scores on the Believemy platform:
<table>
<caption>Learner Progress - Week 1</caption>
<thead>
<tr>
<th scope="col">Learner</th>
<th scope="col">Course</th>
<th scope="col">Progress</th>
<th scope="col">Score</th>
</tr>
</thead>
<tbody>
<tr>
<td>Marie Dupont</td>
<td>HTML & CSS</td>
<td>75%</td>
<td>92/100</td>
</tr>
<tr>
<td>Pierre Martin</td>
<td>JavaScript</td>
<td>45%</td>
<td>88/100</td>
</tr>
<tr>
<td>Sophie Bernard</td>
<td>React</td>
<td>90%</td>
<td>95/100</td>
</tr>
</tbody>
</table>Note the use of scope="col" on header cells, which tells screen readers that these headers apply to columns.
Table with merged cells
The colspan and rowspan attributes allow you to merge cells horizontally or vertically:
<table>
<caption>Weekly Class Schedule</caption>
<thead>
<tr>
<th scope="col">Time</th>
<th scope="col">Monday</th>
<th scope="col">Tuesday</th>
<th scope="col">Wednesday</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">9am - 12pm</th>
<td rowspan="2">HTML Course</td>
<td>CSS Course</td>
<td>Free</td>
</tr>
<tr>
<th scope="row">2pm - 5pm</th>
<td colspan="2">Practical Project</td>
</tr>
</tbody>
</table>In this example:
rowspan="2"makes "HTML Course" span two rowscolspan="2"makes "Practical Project" span two columnsscope="row"indicates that the time cells are row headers
Responsive table with CSS
Tables can be problematic on mobile devices. Here's a technique to make them responsive:
<div class="table-container">
<table class="table-responsive">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>City</th>
<th>Registration</th>
</tr>
</thead>
<tbody>
<tr>
<td data-label="Name">Jean Believemy</td>
<td data-label="Email">jean@example.com</td>
<td data-label="Phone">01 23 45 67 89</td>
<td data-label="City">Paris</td>
<td data-label="Registration">01/15/2024</td>
</tr>
</tbody>
</table>
</div>/* Horizontally scrollable container */
.table-container {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.table-responsive {
width: 100%;
border-collapse: collapse;
}
.table-responsive th,
.table-responsive td {
padding: 12px;
text-align: left;
border-bottom: 1px solid #ddd;
}
/* Alternative: card display on mobile */
@media screen and (max-width: 600px) {
.table-responsive thead {
display: none;
}
.table-responsive tr {
display: block;
margin-bottom: 1rem;
border: 1px solid #ddd;
}
.table-responsive td {
display: flex;
justify-content: space-between;
padding: 10px;
}
.table-responsive td::before {
content: attr(data-label);
font-weight: bold;
}
}This technique uses data-label attributes to display headers on mobile.
HTML table accessibility
Why accessibility is essential
Poorly structured tables are particularly difficult to navigate for screen reader users. An accessible table allows all users to understand the relationships between data.
Accessibility best practices
Here are the essential rules for creating accessible tables:
- Always use
<caption>: describes the table content - Use
<th>for headers: never<td>with bold text - Add the
scopeattribute:colfor columns,rowfor rows - Use
<thead>,<tbody>,<tfoot>: clear semantic structure - Avoid nested tables: unnecessary complexity
<!-- Example of a perfectly accessible table -->
<table aria-describedby="table-desc">
<caption>
Believemy Course Pricing
<span id="table-desc" class="sr-only">
Comparative pricing table by level and duration
</span>
</caption>
<thead>
<tr>
<th scope="col">Course</th>
<th scope="col">Level</th>
<th scope="col">Duration</th>
<th scope="col">Price</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">HTML Fundamentals</th>
<td>Beginner</td>
<td>10 hours</td>
<td>Free</td>
</tr>
<tr>
<th scope="row">Advanced CSS</th>
<td>Intermediate</td>
<td>15 hours</td>
<td>$49</td>
</tr>
</tbody>
</table>
ARIA attributes for complex tables
For tables with complex headers, use the id and headers attributes:
<table>
<thead>
<tr>
<th id="name">Name</th>
<th id="q1">Q1 2024</th>
<th id="q2">Q2 2024</th>
</tr>
</thead>
<tbody>
<tr>
<th id="marie" headers="name">Marie</th>
<td headers="marie q1">150</td>
<td headers="marie q2">180</td>
</tr>
</tbody>
</table>The headers attribute lists the identifiers of associated header cells.
Styling tables with CSS
Recommended base styles
Here's a solid CSS foundation for styling your tables:
/* Reset and base */
table {
width: 100%;
border-collapse: collapse;
margin: 1.5rem 0;
font-size: 0.95rem;
}
/* Headers */
thead {
background-color: #2563eb;
color: white;
}
th {
padding: 1rem;
text-align: left;
font-weight: 600;
}
/* Cells */
td {
padding: 0.875rem 1rem;
border-bottom: 1px solid #e5e7eb;
}
/* Alternating colors */
tbody tr:nth-child(even) {
background-color: #f9fafb;
}
/* Hover effect */
tbody tr:hover {
background-color: #eff6ff;
}
/* Table footer */
tfoot {
background-color: #f3f4f6;
font-weight: 600;
}
Table with rounded borders
To achieve rounded borders on a table, we need to use a specific technique:
table {
border-collapse: separate;
border-spacing: 0;
border: 1px solid #e5e7eb;
border-radius: 8px;
overflow: hidden;
}
th:first-child {
border-top-left-radius: 8px;
}
th:last-child {
border-top-right-radius: 8px;
}
tbody tr:last-child td:first-child {
border-bottom-left-radius: 8px;
}
tbody tr:last-child td:last-child {
border-bottom-right-radius: 8px;
}Use border-collapse: separate to allow rounded borders, then border-spacing: 0 to remove spacing between cells.
Common mistakes to avoid
Using tables for page layout
This is the most common and problematic mistake:
<!-- ❌ BAD: table used for layout -->
<table>
<tr>
<td><nav>Menu...</nav></td>
<td><main>Content...</main></td>
<td><aside>Sidebar...</aside></td>
</tr>
</table>
<!-- ✅ GOOD: use CSS Grid or Flexbox -->
<div class="layout">
<nav>Menu...</nav>
<main>Content...</main>
<aside>Sidebar...</aside>
</div>
Forgetting semantic headers
<!-- ❌ BAD: headers with <td> and bold -->
<table>
<tr>
<td><strong>Name</strong></td>
<td><strong>Age</strong></td>
</tr>
</table>
<!-- ✅ GOOD: use <th> -->
<table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
</table>
Tables too wide without responsive handling
<!-- ❌ BAD: table with many columns without wrapper -->
<table>...15 columns...</table>
<!-- ✅ GOOD: container with horizontal scroll -->
<div style="overflow-x: auto;">
<table>...15 columns...</table>
</div>
Tables and SEO
How Google interprets tables
Search engines can extract and display data from your tables directly in search results. To optimize your tables for SEO:
- Use descriptive headers: Google uses
<th>to understand structure - Add a relevant
<caption>: helps understand context - Structure data correctly:
<thead>,<tbody>,<tfoot> - Avoid images of text: text in tables is indexable
Browser compatibility
The <table> tag and its associated elements enjoy excellent compatibility:
| Browser | Minimum Version | Support |
|---|---|---|
| Chrome | 1.0 | ✅ Full |
| Firefox | 1.0 | ✅ Full |
| Safari | 1.0 | ✅ Full |
| Edge | 12 | ✅ Full |
| Opera | 7.0 | ✅ Full |
| Internet Explorer | 4.0 | ✅ Full |
HTML tables have been supported by all browsers since their earliest versions.
Frequently asked questions about the table tag
What is the difference between <th> and <td>?
The <th> tag (table header) represents a header cell that describes the content of its column or row. It is automatically bold and centered by default. The <td> tag (table data) contains standard table data. Always use <th> for headers to improve accessibility and semantics of your table.
How do I merge cells in an HTML table?
Use the colspan attribute to merge cells horizontally (across multiple columns) and rowspan to merge vertically (across multiple rows). For example, <td colspan="3"> creates a cell that spans 3 columns, while <td rowspan="2"> creates a cell that spans 2 rows.
Can I use tables for website layout?
No, this practice is strongly discouraged and has been considered obsolete for many years. Tables are designed only for displaying tabular data. For layout, use modern CSS technologies like Flexbox or CSS Grid, which offer more flexibility and are much better for accessibility and SEO.
How can I learn HTML and CSS?
To master HTML, CSS, and professional table creation, we recommend following our HTML course. This course will guide you step by step through learning the fundamentals to advanced techniques, with practical exercises and concrete projects.