table
The wrapper for tabular data.
Learn HTML Tables with practical examples for tables, lists, structured data relationships, accessibility, SEO and live practice.
HTML data structures
A table is useful when information belongs in rows and columns. Prices, schedules, comparison data, analytics, invoices and technical specifications are normal table use cases.
Good table markup is not only about making boxes on screen. The browser, screen readers and search engines need to understand which cells are labels, which cells are values and what the table is about.
The most important mindset is this: if the data still makes sense as a spreadsheet, a table is probably a good choice. If you only want columns for design, use CSS layout instead.
The wrapper for tabular data.
A clear title or short explanation for the table.
Optional groups that make larger tables easier to understand.
Rows, header cells and normal data cells.
Table anatomy
A table is useful when the reader needs to compare values across rows and columns. The HTML should preserve those relationships so visual users, keyboard users and screen reader users can all understand the same data.
<th scope="col">Price</th>
<table>
The container for data that belongs in rows and columns.
<caption>
A short title that explains what the table compares.
<th scope="col">
A header cell names a row or column so the data has context.
<td>
A data cell contains the actual value connected to headers.
When users compare structured data across rows and columns.
When items belong together but do not need row-and-column comparison.
When each item is a standalone object and comparison is not the main task.
Syntax and structure
Use th for labels and td for values. Use scope when a header clearly labels a row or column.
<table> <caption>Driving lesson prices</caption> <thead> <tr> <th scope="col">Item</th> <th scope="col">Duration</th> <th scope="col">Price</th> </tr> </thead> <tbody> <tr> <th scope="row">Single lesson</th> <td>60 minutes</td> <td>EUR 75</td> </tr> </tbody> </table>
<table> <tr> <td><h1>Hero title</h1></td> <td><img src="car.jpg" alt=""></td> </tr> </table>
HTML quick reference
Use these patterns when you need the syntax quickly. Each example has its own anchor, so search engines and readers can land directly on the exact pattern instead of only at the top of the lesson.
A clean version of the markup from this lesson. Use it when you need the correct HTML shape quickly.
<table> <caption>Driving lesson prices</caption> <thead> <tr> <th scope="col">Item</th> <th scope="col">Duration</th> <th scope="col">Price</th> </tr> </thead> <tbody> <tr> <th scope="row">Single lesson</th> <td>60 minutes</td> <td>EUR 75</td> </tr> </tbody> </table>
Meaningful markup that stays understandable before CSS and JavaScript are added.
The starting point from the practice lab. Change the HTML first, then use CSS only for presentation.
<main class="demo-card"> <h1>Lesson prices</h1> <table> <caption>Example lesson price list</caption> <thead> <tr><th scope="col">Item</th><th scope="col">Includes</th><th scope="col">Price</th></tr> </thead> <tbody> <tr><th scope="row">Start package</th><td>15 lessons and exam</td><td>EUR 1425</td></tr> <tr><th scope="row">Single lesson</th><td>60 minutes</td><td>EUR 75</td></tr> </tbody> </table> </main> <style> body { margin: 0; min-height: 100vh; display: grid; place-items: center; font-family: Inter, system-ui, sans-serif; background: #07111f; color: white; } .demo-card { width: min(820px, calc(100% - 32px)); padding: 34px; border-radius: 24px; background: #101a2d; box-shadow: 0 30px 80px rgba(0, 0, 0, 0.3); } h1 { margin: 0 0 18px; font-size: clamp(32px, 6vw, 54px); line-height: 1; } table { width: 100%; border-collapse: collapse; color: #f7f7f4; } caption { caption-side: top; margin-bottom: 12px; color: #8cffc1; font-weight: 900; text-align: left; } th, td { border-bottom: 1px solid rgba(255, 255, 255, 0.14); padding: 13px 14px; text-align: left; vertical-align: top; } th { color: #8cffc1; font-weight: 900; } ul, ol { display: grid; gap: 10px; margin: 0; padding-left: 24px; color: #cfd8e6; } li::marker { color: #8cffc1; font-weight: 900; } dl { margin: 0; } </style>
A complete practice snippet that shows how the HTML behaves in context.
A weak pattern from the lesson. Use it as a warning sign when reviewing real pages.
<table> <tr> <td><h1>Hero title</h1></td> <td><img src="car.jpg" alt=""></td> </tr> </table>
A recognizable mistake you can search for and refactor.
Rules that matter
Tables and lists are small elements with big structural value. They help users scan, compare, follow steps and understand how pieces of information belong together.
If the content is layout, use CSS grid or flexbox instead.
A caption gives the table a readable subject and helps assistive technology.
Bold td text is not the same as a real header cell.
thead, tbody and tfoot make repeated data easier to scan and maintain.
A table should not become a dumping ground for full page sections.
Tables often need scrolling, simplified columns or responsive treatment.
Production thinking
Tables matter because data loses value when the relationship between values is unclear. Strong table markup keeps that relationship visible to users and machines.
Screen reader users rely on header relationships. Correct th, scope and caption markup turns a visual grid into understandable data.
For large tables, plan sorting, filtering, sticky headers, horizontal scroll and export behavior early. The HTML structure is the foundation.
Search engines can understand structured information better when table content is real text with clear headers and a relevant caption.
Live code lab
Edit the HTML or CSS, then use Run to refresh the preview. The preview is isolated, so links and forms stay inside this practice area.
Mini assignment
Practice assignment
Try it yourself
Self-check
Do not only read this page. Answer these questions out loud or write the answers in your own notes. If one answer feels vague, revisit the examples before moving on.