Table Element
The <caption> element provides a title or description for its parent <table>. It helps users understand what the table represents before reading its contents. Captions are especially important for accessibility, as they give screen reader users immediate context about the table’s purpose.
Accessibility Requirement
Every table should have a caption. It’s one of the most important accessibility features you can add to make your tables understandable for all users.
Interactive code playground requires JavaScript. Here's the code:
<table>
<caption>Employee Directory - Engineering Team</caption>
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Role</th>
<th scope="col">Experience</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alice Chen</td>
<td>Senior Engineer</td>
<td>8 years</td>
</tr>
<tr>
<td>Bob Martinez</td>
<td>Tech Lead</td>
<td>12 years</td>
</tr>
<tr>
<td>Carol Davis</td>
<td>Software Engineer</td>
<td>3 years</td>
</tr>
</tbody>
</table>
<style>
table {
border-collapse: collapse;
width: 100%;
}
caption {
font-size: 1.2em;
font-weight: bold;
margin-bottom: 0.5em;
text-align: left;
color: #333;
}
th, td {
border: 1px solid #ddd;
padding: 10px;
text-align: left;
}
thead {
background-color: #f4f4f4;
}
</style>
< caption > Table title or description </ caption >
<!-- table rows and cells -->
The <caption> element must be the first child of the <table> element, appearing immediately after the opening <table> tag.
The <caption> element supports all global HTML attributes .
Interactive code playground requires JavaScript. Here's the code:
<table>
<caption>Monthly Website Statistics</caption>
<thead>
<tr>
<th scope="col">Metric</th>
<th scope="col">Value</th>
<th scope="col">Change</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Visitors</th>
<td>45,200</td>
<td>+12%</td>
</tr>
<tr>
<th scope="row">Page Views</th>
<td>128,400</td>
<td>+8%</td>
</tr>
<tr>
<th scope="row">Bounce Rate</th>
<td>32%</td>
<td>-5%</td>
</tr>
</tbody>
</table>
<style>
table {
border-collapse: collapse;
width: 100%;
}
caption {
font-size: 1.3em;
font-weight: bold;
margin-bottom: 10px;
color: #2c3e50;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
}
thead {
background-color: #3498db;
color: white;
}
tbody th {
background-color: #ecf0f1;
}
</style>
Interactive code playground requires JavaScript. Here's the code:
<table>
<caption>
<strong>Q4 2024 Sales Performance</strong>
<br>
<small>All figures in thousands of dollars</small>
</caption>
<thead>
<tr>
<th scope="col">Region</th>
<th scope="col">Q3</th>
<th scope="col">Q4</th>
<th scope="col">Growth</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">North</th>
<td>$342</td>
<td>$389</td>
<td>+13.7%</td>
</tr>
<tr>
<th scope="row">South</th>
<td>$298</td>
<td>$315</td>
<td>+5.7%</td>
</tr>
<tr>
<th scope="row">East</th>
<td>$421</td>
<td>$456</td>
<td>+8.3%</td>
</tr>
</tbody>
</table>
<style>
table {
border-collapse: collapse;
width: 100%;
}
caption {
text-align: left;
margin-bottom: 10px;
}
caption strong {
font-size: 1.2em;
color: #2c3e50;
}
caption small {
color: #7f8c8d;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: right;
}
th[scope="col"], th[scope="row"] {
text-align: left;
}
thead {
background-color: #34495e;
color: white;
}
</style>
Interactive code playground requires JavaScript. Here's the code:
<table>
<caption>
Student Grades - Spring 2024
<details>
<summary>About this data</summary>
<p>Final grades for Computer Science 101.
Passing grade is 60 or above.
Data collected May 2024.</p>
</details>
</caption>
<thead>
<tr>
<th scope="col">Student</th>
<th scope="col">Midterm</th>
<th scope="col">Final</th>
<th scope="col">Grade</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alex Kim</td>
<td>85</td>
<td>92</td>
<td>A</td>
</tr>
<tr>
<td>Jordan Lee</td>
<td>78</td>
<td>81</td>
<td>B</td>
</tr>
</tbody>
</table>
<style>
table {
border-collapse: collapse;
width: 100%;
}
caption {
font-size: 1.2em;
font-weight: bold;
margin-bottom: 10px;
text-align: left;
}
details {
font-size: 0.9em;
font-weight: normal;
margin-top: 5px;
}
summary {
cursor: pointer;
color: #3498db;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
}
thead {
background-color: #f8f9fa;
}
</style>
You can position the caption above or below the table using the caption-side CSS property:
Interactive code playground requires JavaScript. Here's the code:
<table>
<caption>Caption at Top (Default)</caption>
<thead>
<tr>
<th scope="col">Column 1</th>
<th scope="col">Column 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data 1</td>
<td>Data 2</td>
</tr>
</tbody>
</table>
<style>
table { border-collapse: collapse; width: 100%; }
caption {
caption-side: top;
font-weight: bold;
padding: 10px;
background-color: #e8f4f8;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
}
</style> Interactive code playground requires JavaScript. Here's the code:
<table>
<caption>Caption at Bottom</caption>
<thead>
<tr>
<th scope="col">Column 1</th>
<th scope="col">Column 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data 1</td>
<td>Data 2</td>
</tr>
</tbody>
</table>
<style>
table { border-collapse: collapse; width: 100%; }
caption {
caption-side: bottom;
font-style: italic;
padding: 10px;
text-align: right;
color: #666;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
}
</style>
Interactive code playground requires JavaScript. Here's the code:
<table>
<caption style="text-align: center;">Centered Caption</caption>
<tbody>
<tr><td>Data 1</td><td>Data 2</td></tr>
</tbody>
</table>
<table style="margin-top: 20px;">
<caption style="text-align: left;">Left-Aligned Caption</caption>
<tbody>
<tr><td>Data 1</td><td>Data 2</td></tr>
</tbody>
</table>
<table style="margin-top: 20px;">
<caption style="text-align: right;">Right-Aligned Caption</caption>
<tbody>
<tr><td>Data 1</td><td>Data 2</td></tr>
</tbody>
</table>
<style>
table {
border-collapse: collapse;
width: 100%;
}
caption {
font-weight: bold;
padding: 8px;
background-color: #f0f0f0;
}
td {
border: 1px solid #ddd;
padding: 8px;
}
</style>
Interactive code playground requires JavaScript. Here's the code:
<table>
<caption class="fancy-caption">
<span class="icon">📊</span>
Data Analysis Report
</caption>
<thead>
<tr>
<th scope="col">Metric</th>
<th scope="col">Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>Total Users</td>
<td>1,245</td>
</tr>
<tr>
<td>Active Today</td>
<td>892</td>
</tr>
</tbody>
</table>
<style>
table {
border-collapse: collapse;
width: 100%;
}
.fancy-caption {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 15px;
font-size: 1.3em;
font-weight: bold;
text-align: left;
border-radius: 8px 8px 0 0;
}
.icon {
margin-right: 8px;
}
th, td {
border: 1px solid #ddd;
padding: 10px;
text-align: left;
}
thead {
background-color: #f8f9fa;
}
</style>
Captions provide crucial context for assistive technology users:
Screen readers announce the caption before reading table contents
Users can decide if the table is relevant before exploring it
Context is immediate - users don’t have to scan the entire table to understand its purpose
Navigation is easier - screen readers can jump between tables using captions
Be Descriptive
Good: “Monthly Sales by Region - Q4 2024”
Bad: “Table 1”
Be Concise
Good: “Employee Contact Information”
Bad: “This table shows employee names, phone numbers, email addresses, and department assignments”
Front-Load Keywords
Good: “Pricing Comparison - Enterprise Plans”
Bad: “A comparison of our enterprise plan pricing”
Avoid Redundancy
Good: “Course Schedule - Fall 2024”
Bad: “Table of Course Schedule - Fall 2024”
Use for: Brief title visible to all users
< caption > Monthly Budget - March 2024 </ caption >
Use for: Additional context in expandable details
< summary > Table structure </ summary >
Rows represent departments, columns show
expenses by category. Last row contains totals.
✅ Always include a caption for every table
✅ Place it first as the first child of <table>
✅ Make it descriptive but concise
✅ Use semantic HTML within the caption (like <strong>, <em>)
✅ Style consistently across your site
❌ Don’t use generic text like “Table 1” or “Data”
❌ Don’t place it elsewhere - it must be the first child
❌ Don’t hide it with CSS unless you provide an alternative
❌ Don’t duplicate information already in headers
❌ Don’t make it too long - keep it scannable
/* Basic caption styling */
caption-side : top ; /* or bottom */
text-align : left ; /* left, center, right */
/* Background and borders */
background-color : # f8f9fa ;
border : 1 px solid # dee2e6 ;
border-bottom : none ; /* if table has borders */
background : linear-gradient ( to right , # 4facfe , # 00f2fe );
border-radius : 8 px 8 px 0 0 ;
< span aria-hidden = " true " > 📈 </ span >
< time datetime = " 2024-01 " > January 2024 </ time >
< div class = " caption-title " > Product Inventory </ div >
< div class = " caption-subtitle " > Last updated: < time > 2024-03-15 </ time ></ div >
The <caption> element is supported in all browsers:
✅ Chrome (all versions)
✅ Firefox (all versions)
✅ Safari (all versions)
✅ Edge (all versions)
✅ Opera (all versions)
✅ Internet Explorer (all versions)
The caption-side CSS property is supported in all modern browsers but has limited support in older versions of Internet Explorer.