Creating HTML Tables
Tables are essential for displaying structured data on web pages. In this tutorial, you’ll learn how to create tables with headers, rows, and columns, and how to style them for better readability!
Why Use Tables?
Tables are perfect for displaying data that has a clear row-and-column structure, such as:
- Product pricing comparisons
- Sports scores and standings
- Class schedules
- Financial data
- Contact lists
- Scientific data
Important: Tables should be used for tabular data, not for page layout! Use CSS Grid or Flexbox for layout instead.
Basic Table Structure
Every HTML table is built from these essential elements:
<table>— The container for the entire table<tr>— Table row (each row of data)<td>— Table data cell (a single cell in the table)<th>— Table header cell (for column or row headings)
Here’s the simplest possible table:
<table>
<tr>
<td>Row 1, Cell 1</td>
<td>Row 1, Cell 2</td>
</tr>
<tr>
<td>Row 2, Cell 1</td>
<td>Row 2, Cell 2</td>
</tr>
</table>Your First Complete Table
Let’s build a table with headers and multiple rows:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Student Grades</title>
</head>
<body>
<h1>Class Grades</h1>
<table>
<tr>
<th>Student Name</th>
<th>Subject</th>
<th>Grade</th>
</tr>
<tr>
<td>Sarah Johnson</td>
<td>Math</td>
<td>A</td>
</tr>
<tr>
<td>Mike Chen</td>
<td>Math</td>
<td>B+</td>
</tr>
<tr>
<td>Emma Davis</td>
<td>Math</td>
<td>A-</td>
</tr>
</table>
</body>
</html>How it works:
- The first
<tr>contains<th>elements that create bold, centered header cells - Each additional
<tr>represents one student - Each
<td>contains one piece of information
Table Sections: thead, tbody, and tfoot
For better organization and accessibility, divide your table into semantic sections:
<table>
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Stock</th>
</tr>
</thead>
<tbody>
<tr>
<td>Laptop</td>
<td>$999</td>
<td>15</td>
</tr>
<tr>
<td>Mouse</td>
<td>$25</td>
<td>50</td>
</tr>
<tr>
<td>Keyboard</td>
<td>$75</td>
<td>30</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Total Items</td>
<td></td>
<td>95</td>
</tr>
</tfoot>
</table>Benefits:
<thead>— Groups header rows (great for accessibility)<tbody>— Contains the main table data<tfoot>— Contains footer content like totals- Screen readers can better understand and navigate your tables
- You can style each section differently with CSS
Adding Basic Styling
Plain HTML tables look pretty bland. Let’s add some CSS to make them more readable:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Styled Table</title>
<style>
table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
}
th, td {
padding: 12px;
text-align: left;
border: 1px solid #ddd;
}
th {
background-color: #4CAF50;
color: white;
font-weight: bold;
}
tr:nth-child(even) {
background-color: #f2f2f2;
}
tr:hover {
background-color: #ddd;
}
</style>
</head>
<body>
<h1>Product Inventory</h1>
<table>
<thead>
<tr>
<th>Product</th>
<th>Category</th>
<th>Price</th>
<th>In Stock</th>
</tr>
</thead>
<tbody>
<tr>
<td>Laptop</td>
<td>Electronics</td>
<td>$999</td>
<td>Yes</td>
</tr>
<tr>
<td>Desk Chair</td>
<td>Furniture</td>
<td>$299</td>
<td>Yes</td>
</tr>
<tr>
<td>Monitor</td>
<td>Electronics</td>
<td>$399</td>
<td>No</td>
</tr>
</tbody>
</table>
</body>
</html>Key styling concepts:
border-collapse: collapseremoves double bordersnth-child(even)creates alternating row colors (zebra striping):hoverhighlights rows when you mouse over them
Column Spanning
Use colspan to make a cell span multiple columns:
<table>
<thead>
<tr>
<th colspan="3">Q1 Sales Report</th>
</tr>
<tr>
<th>Month</th>
<th>Sales</th>
<th>Growth</th>
</tr>
</thead>
<tbody>
<tr>
<td>January</td>
<td>$50,000</td>
<td>5%</td>
</tr>
<tr>
<td>February</td>
<td>$55,000</td>
<td>10%</td>
</tr>
<tr>
<td>March</td>
<td>$60,000</td>
<td>9%</td>
</tr>
</tbody>
</table>The first header cell spans all 3 columns, creating a title row for the table.
Row Spanning
Use rowspan to make a cell span multiple rows:
<table>
<thead>
<tr>
<th>Department</th>
<th>Employee</th>
<th>Role</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="2">Engineering</td>
<td>Alice Smith</td>
<td>Developer</td>
</tr>
<tr>
<td>Bob Jones</td>
<td>Designer</td>
</tr>
<tr>
<td rowspan="2">Sales</td>
<td>Carol White</td>
<td>Account Manager</td>
</tr>
<tr>
<td>David Brown</td>
<td>Sales Rep</td>
</tr>
</tbody>
</table>The department names span two rows each, avoiding repetition.
Captions
Add a caption to describe your table:
<table>
<caption>Monthly Website Traffic - 2024</caption>
<thead>
<tr>
<th>Month</th>
<th>Visitors</th>
<th>Page Views</th>
</tr>
</thead>
<tbody>
<tr>
<td>January</td>
<td>10,500</td>
<td>25,000</td>
</tr>
<tr>
<td>February</td>
<td>12,300</td>
<td>28,500</td>
</tr>
</tbody>
</table>The <caption> element provides a title that’s semantically associated with the table, which is excellent for accessibility!
Responsive Tables
Tables can be tricky on mobile devices. Here’s a simple responsive solution:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Responsive Table</title>
<style>
.table-container {
overflow-x: auto;
}
table {
width: 100%;
border-collapse: collapse;
min-width: 500px;
}
th, td {
padding: 12px;
border: 1px solid #ddd;
text-align: left;
}
th {
background-color: #333;
color: white;
}
</style>
</head>
<body>
<h1>Responsive Product Table</h1>
<div class="table-container">
<table>
<thead>
<tr>
<th>Product</th>
<th>Category</th>
<th>Price</th>
<th>Rating</th>
<th>Stock</th>
</tr>
</thead>
<tbody>
<tr>
<td>Wireless Headphones</td>
<td>Electronics</td>
<td>$79.99</td>
<td>4.5/5</td>
<td>25</td>
</tr>
<tr>
<td>Coffee Maker</td>
<td>Appliances</td>
<td>$49.99</td>
<td>4.2/5</td>
<td>15</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>The overflow-x: auto allows the table to scroll horizontally on small screens instead of breaking the layout.
Scope Attribute for Accessibility
Use the scope attribute to help screen readers understand table structure:
<table>
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Age</th>
<th scope="col">Country</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Sarah</th>
<td>28</td>
<td>USA</td>
</tr>
<tr>
<th scope="row">Ahmed</th>
<td>35</td>
<td>Egypt</td>
</tr>
</tbody>
</table>scope="col"indicates a column headerscope="row"indicates a row header
Common Mistakes to Avoid
Forgetting Table Rows
Problematic example:
<table>
<td>Data 1</td>
<td>Data 2</td>
</table>Improved example:
<table>
<tr>
<td>Data 1</td>
<td>Data 2</td>
</tr>
</table>Every cell must be inside a <tr> (table row)!
Using Tables for Layout
Problematic example:
<table>
<tr>
<td>Header</td>
</tr>
<tr>
<td>Sidebar</td>
<td>Main Content</td>
</tr>
</table>Improved example:
<header>Header</header>
<div class="container">
<aside>Sidebar</aside>
<main>Main Content</main>
</div>Use CSS Grid or Flexbox for page layout, not tables!
Inconsistent Column Counts
Problematic example:
<table>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td>D</td>
<td>E</td>
</tr>
</table>Improved example:
<table>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td>D</td>
<td>E</td>
<td>F</td>
</tr>
</table>Each row should have the same number of columns (unless using colspan/rowspan).
Try It Yourself
Ready to practice? Try these challenges:
Challenge 1: Simple Schedule (Basic)
Create a weekly class schedule table with:
- Headers for days of the week (Monday-Friday)
- Rows for time slots (9 AM, 10 AM, 11 AM)
- Fill in with sample class names
- Add basic borders and padding
Challenge 2: Product Comparison (Intermediate)
Build a product comparison table with:
- Three products to compare
- At least 5 features (price, rating, weight, color, warranty)
- Use
<thead>,<tbody>, and<tfoot> - Add alternating row colors
- Include a caption
Challenge 3: Complex Data Table (Advanced)
Create a financial report table with:
- A title using
colspanthat spans all columns - Quarterly data with row headers using
scope="row" - Category subtotals using
colspan - A footer row with yearly totals
- Responsive container for mobile viewing
- Hover effects on rows
What You Learned
Congratulations! You now know:
- How to create tables using
<table>,<tr>,<td>, and<th> - How to structure tables with
<thead>,<tbody>, and<tfoot> - How to use colspan and rowspan for complex layouts
- How to style tables for better readability
- How to make tables responsive and accessible
Next Steps
Now that you can create tables, explore these related tutorials:
- Semantic HTML — Use proper HTML5 elements
- Forms — Collect user input with forms
- Contact Forms — Build functional contact forms
- Portfolio Page — Create a project showcase
Want to experiment with tables? Try our interactive HTML editor!