Tables are used to display data in rows and columns, making it easy to compare and organize information. HTML provides a complete set of elements for creating structured tabular data.
The Table Element
The <table> element creates a table. It acts as a container for all table content including rows, cells, and headers.
<table>
<!-- Table content goes here -->
</table>Basic Table Structure
A table is built with four main elements:
<table>- The container<tr>- Table row<td>- Table data (cell)<th>- Table header (cell)
A Simple Table
<table>
<tr>
<th>Name</th>
<th>Age</th>
<th>City</th>
</tr>
<tr>
<td>John Doe</td>
<td>28</td>
<td>New York</td>
</tr>
<tr>
<td>Jane Smith</td>
<td>34</td>
<td>Los Angeles</td>
</tr>
<tr>
<td>Mike Johnson</td>
<td>42</td>
<td>Chicago</td>
</tr>
</table>This creates a table with headers and three rows of data.
The TR Element (Table Row)
The <tr> element defines a row in the table. Each row contains one or more cells (td or th).
<table>
<tr>
<!-- First row -->
</tr>
<tr>
<!-- Second row -->
</tr>
<tr>
<!-- Third row -->
</tr>
</table>The TD Element (Table Data)
The <td> element defines a standard data cell in a table. These cells contain the actual data.
<table>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
</table>The TH Element (Table Header)
The <th> element defines a header cell. By default, browsers display th content in bold and centered.
<table>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
</tr>
<tr>
<td>Data 1</td>
<td>Data 2</td>
<td>Data 3</td>
</tr>
</table>Practical Examples
Student Grade Table
<table>
<tr>
<th>Student Name</th>
<th>Math</th>
<th>English</th>
<th>Science</th>
</tr>
<tr>
<td>Alice Brown</td>
<td>95</td>
<td>88</td>
<td>92</td>
</tr>
<tr>
<td>Bob Wilson</td>
<td>87</td>
<td>91</td>
<td>85</td>
</tr>
<tr>
<td>Carol Davis</td>
<td>92</td>
<td>89</td>
<td>94</td>
</tr>
</table>Product Price List
<table>
<tr>
<th>Product</th>
<th>Price</th>
<th>Stock</th>
</tr>
<tr>
<td>Laptop</td>
<td>$999</td>
<td>15</td>
</tr>
<tr>
<td>Mouse</td>
<td>$25</td>
<td>120</td>
</tr>
<tr>
<td>Keyboard</td>
<td>$75</td>
<td>45</td>
</tr>
<tr>
<td>Monitor</td>
<td>$350</td>
<td>28</td>
</tr>
</table>Schedule Table
<table>
<tr>
<th>Time</th>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
</tr>
<tr>
<td>9:00 AM</td>
<td>Math</td>
<td>Science</td>
<td>History</td>
</tr>
<tr>
<td>10:30 AM</td>
<td>English</td>
<td>Math</td>
<td>Science</td>
</tr>
<tr>
<td>1:00 PM</td>
<td>Art</td>
<td>Music</td>
<td>Physical Ed</td>
</tr>
</table>Comparison Table
<table>
<tr>
<th>Feature</th>
<th>Basic Plan</th>
<th>Pro Plan</th>
<th>Enterprise</th>
</tr>
<tr>
<td>Storage</td>
<td>10 GB</td>
<td>100 GB</td>
<td>Unlimited</td>
</tr>
<tr>
<td>Users</td>
<td>1</td>
<td>5</td>
<td>Unlimited</td>
</tr>
<tr>
<td>Support</td>
<td>Email</td>
<td>Email + Chat</td>
<td>24/7 Phone</td>
</tr>
<tr>
<td>Price</td>
<td>$9/month</td>
<td>$29/month</td>
<td>$99/month</td>
</tr>
</table>Adding Borders
By default, tables have no visible borders. You can add borders with the border attribute (though CSS is preferred):
<table border="1">
<tr>
<th>Name</th>
<th>Email</th>
</tr>
<tr>
<td>John Doe</td>
<td>john@example.com</td>
</tr>
</table>For better styling, use CSS instead:
table {
border-collapse: collapse;
width: 100%;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #4CAF50;
color: white;
}
tr:nth-child(even) {
background-color: #f2f2f2;
}
tr:hover {
background-color: #ddd;
}Header Scope Attribute
The scope attribute on th elements improves accessibility by specifying whether the header is for a column or row:
<table>
<tr>
<th scope="col">Product</th>
<th scope="col">Price</th>
<th scope="col">Quantity</th>
</tr>
<tr>
<th scope="row">Laptop</th>
<td>$999</td>
<td>5</td>
</tr>
<tr>
<th scope="row">Phone</th>
<td>$599</td>
<td>10</td>
</tr>
</table>Empty Cells
You can have empty cells in a table. They still need the td or th element:
<table border="1">
<tr>
<th>Name</th>
<th>Score</th>
<th>Status</th>
</tr>
<tr>
<td>John</td>
<td>95</td>
<td>Passed</td>
</tr>
<tr>
<td>Jane</td>
<td></td>
<td>Pending</td>
</tr>
<tr>
<td>Mike</td>
<td>87</td>
<td></td>
</tr>
</table>Tables with Links and Other Content
Table cells can contain any HTML content, including links, images, and formatted text:
<table>
<tr>
<th>Website</th>
<th>Description</th>
<th>Link</th>
</tr>
<tr>
<td><strong>MDN Web Docs</strong></td>
<td>Comprehensive web development documentation</td>
<td><a href="https://developer.mozilla.org">Visit</a></td>
</tr>
<tr>
<td><strong>W3Schools</strong></td>
<td>Interactive tutorials and examples</td>
<td><a href="https://www.w3schools.com">Visit</a></td>
</tr>
<tr>
<td><strong>CSS-Tricks</strong></td>
<td>Tips and techniques for CSS</td>
<td><a href="https://css-tricks.com">Visit</a></td>
</tr>
</table>When to Use Tables
✅ Use tables for:
- Displaying tabular data (spreadsheet-like information)
- Comparing data across categories
- Showing schedules and timetables
- Price lists and product comparisons
- Financial reports
- Statistical data
- Any data with rows and columns relationship
❌ Don't use tables for:
- Page layout (use CSS Grid or Flexbox instead)
- Positioning elements on the page
- Creating columns for text
- Navigation menus
- Photo galleries
- Any non-tabular content
Accessibility Considerations
♿ Accessibility Best Practices:
- Always use
<th>for header cells - Include
scopeattribute on header cells - Keep tables simple and avoid nested tables
- Provide a caption or heading above the table
- Ensure sufficient color contrast
- Make sure tables are keyboard navigable
- Test with screen readers
Common Mistakes
❌ Common mistakes:
- Forgetting to wrap cells in tr elements
- Using different numbers of cells per row (creates layout issues)
- Using tables for layout instead of tabular data
- Not using th elements for headers
- Forgetting closing tags
- Putting content directly in table (must be in tr/td/th)
Wrong Structure
<!-- ❌ Wrong: Content directly in table -->
<table>
Some text
<tr><td>Data</td></tr>
</table>
<!-- ❌ Wrong: Cells not in rows -->
<table>
<td>Data 1</td>
<td>Data 2</td>
</table>
<!-- ❌ Wrong: Inconsistent cell count -->
<table>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 1</td>
</tr>
</table>Correct Structure
<!-- ✅ Correct: Proper structure -->
<table>
<tr>
<td>Data 1</td>
<td>Data 2</td>
</tr>
</table>
<!-- ✅ Correct: All cells in rows -->
<table>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 3</td>
<td>Cell 4</td>
</tr>
</table>
<!-- ✅ Correct: Consistent structure -->
<table>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
<tr>
<td>Data 1</td>
<td>Data 2</td>
</tr>
</table>Best Practices
✅ Do:
- Use tables only for tabular data
- Include header rows with th elements
- Keep tables simple and readable
- Use scope attribute for accessibility
- Ensure consistent number of cells per row
- Style tables with CSS, not HTML attributes
- Test on different screen sizes
Key Takeaways
<table>creates a table container<tr>defines a table row<td>defines a data cell<th>defines a header cell- Each row should have the same number of cells
- Use tables only for tabular data, not layout
- Include
scopeattribute on headers for accessibility - Tables can contain any HTML content in cells
What's Next?
Now that you understand basic table structure, you're ready to learn about table headers and footers. In the next lesson, we'll explore the thead, tbody, and tfoot elements for better table organization and semantic structure.