HTML Tables

Present tabular data with semantic, accessible HTML tables

Introduction to HTML Tables

What are HTML Tables?

HTML tables display data in rows and columns. They’re ideal for tabular information like schedules, price lists, and comparison charts.

Tables are built using a combination of elements: <table>, <tr>, <th>, and <td>, often organized into <thead>, <tbody>, and <tfoot>. When used correctly, tables make it easy for users and assistive technologies to scan and compare data.

Basic Table Structure

Example: Simple Table
Language Type Usage
HTML Markup Structure of web pages
CSS Style Sheet Presentation and layout
JavaScript Programming Interactivity and logic
HTML Code:
<table>
    <thead>
        <tr>
            <th>Language</th>
            <th>Type</th>
            <th>Usage</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>HTML</td>
            <td>Markup</td>
            <td>Structure of web pages</td>
        </tr>
    </tbody>
</table>

All <table> Attributes

In HTML5, the <table> element has one legacy presentational attribute (border) plus all global attributes. Layout, spacing, borders, and width should be handled with CSS—not obsolete HTML attributes.

Attribute Values Description Example
border Non-negative integer or empty string Obsolete. Draws a border around the table and cells. Use CSS border on table, th, and td instead. <table border="1">
cellpadding Pixels (legacy) Obsolete. Space inside cells. Use CSS padding on th/td. <table cellpadding="8">
cellspacing Pixels (legacy) Obsolete. Space between cells. Use CSS border-spacing or border-collapse. <table cellspacing="0">
width Length or percentage Obsolete. Table width. Use CSS width or responsive wrappers. <table width="100%">
height Length or percentage Obsolete. Table height. Use CSS min-height / height. <table height="300">
align left, center, right Obsolete. Horizontal alignment of the table on the page. Use CSS margin or flex/grid on a wrapper. <table align="center">
bgcolor Color name or hex Obsolete. Background color. Use CSS background-color. <table bgcolor="#f8f9fa">
frame void, above, below, hsides, vsides, lhs, rhs, box, border Obsolete. Which outer borders to show. Use CSS borders. <table frame="box">
rules none, groups, rows, cols, all Obsolete. Which inner grid lines to show. Use CSS border on rows/cells. <table rules="rows">
summary Text Obsolete. Short description for assistive tech. Use <caption> instead. <table summary="Sales by region">
id Global Unique identifier for linking, CSS, or JavaScript. <table id="price-list">
class Global CSS framework or custom class names (e.g. Bootstrap table). <table class="table table-striped">
style Global Inline CSS (prefer external stylesheets). <table style="width:100%; border-collapse:collapse;">
title Global Advisory tooltip on hover. <table title="Employee directory">
lang / dir Global Language and text direction of table content. <table lang="en" dir="ltr">
hidden Global Boolean. Hides the table until the attribute is removed. <table hidden>
role ARIA Usually unnecessary—<table> already exposes table semantics. Avoid overriding unless you know ARIA patterns. <table role="table">
aria-label ARIA Accessible name when no visible <caption> is provided (caption is preferred). <table aria-label="Order history">
data-* Global Custom data for scripts (sorting, filtering, export). <table data-source="api/users">
Example: Modern table styling with CSS (recommended)
<!-- Avoid border="", cellpadding="", width="" on table -->
<table class="data-table">
    <caption>Product Inventory</caption>
    <thead>...</thead>
    <tbody>...</tbody>
</table>

<style>
.data-table {
    width: 100%;
    border-collapse: collapse;
}
.data-table th,
.data-table td {
    border: 1px solid #dee2e6;
    padding: 0.75rem;
}
</style>
Tip: Always pair a styled <table> with semantic child elements (caption, thead, tbody, th) so the structure stays meaningful even when presentation comes from CSS.

Uses of Table Semantic Tags

Semantic table tags describe what each part of the table means, not just how it looks. Screen readers use them to announce headers with data cells; browsers use them for default styling and printing; developers use them to write clearer, maintainable markup.

Tag Purpose / Use When to use Key attributes
<table> Root container for tabular data Schedules, price lists, reports, comparisons—any data in rows and columns class, id, legacy border
<caption> Title or summary of the entire table Always add one for accessibility; replaces obsolete summary on <table> Global attributes; style with CSS caption-side
<colgroup> Groups one or more columns for shared styling Highlight columns, set widths, or apply background colors to entire columns at once Global attributes; contains <col> elements
<col> Represents a single column (or span of columns) Inside <colgroup>; target columns without repeating classes on every cell span (number of columns), style, class
<thead> Group of header rows Column labels at the top; repeated on each printed page in some browsers Global attributes; contains <tr> with <th>
<tbody> Group of main data rows Primary table content; a table may have multiple <tbody> sections Global attributes; contains <tr> with <td> or <th>
<tfoot> Group of footer/summary rows Totals, averages, notes—data that summarizes the body Global attributes; can appear before <tbody> in HTML (renders at bottom)
<tr> One horizontal row of cells Every row of headers or data; must live inside thead, tbody, or tfoot Global attributes
<th> Header cell (row or column label) Column titles in <thead>; row labels in the first column; total labels in <tfoot> scope (col, row, colgroup, rowgroup), colspan, rowspan, abbr, headers
<td> Standard data cell Actual values in the table body or footer (not labels) colspan, rowspan, headers (for complex tables)

Typical semantic structure

Elements must appear in this order inside <table>: captioncolgrouptheadtfoottbody (one or more). Each row (tr) holds cells (th or td).

HTML Code: Semantic table skeleton
<table>
    <caption>Monthly Team Performance Report</caption>

    <colgroup>
        <col class="col-team">
        <col span="2" class="col-metrics">
        <col class="col-status">
    </colgroup>

    <thead>
        <tr>
            <th scope="col">Team</th>
            <th scope="col">Tasks Completed</th>
            <th scope="col">Pending Tasks</th>
            <th scope="col">Status</th>
        </tr>
    </thead>

    <tfoot>
        <tr>
            <th scope="row">Total</th>
            <td>81</td>
            <td>15</td>
            <td>Overall Good</td>
        </tr>
    </tfoot>

    <tbody>
        <tr>
            <th scope="row">Frontend</th>
            <td>42</td>
            <td>6</td>
            <td>On Track</td>
        </tr>
        <tr>
            <th scope="row">Backend</th>
            <td>39</td>
            <td>9</td>
            <td>Needs Review</td>
        </tr>
    </tbody>
</table>

Real-world uses of each semantic tag

  • <caption> — Names the table (“Q2 Sales by Region”) so users know what they are reading without scanning every cell.
  • <thead> — Holds column headers; screen readers repeat them when navigating down a column.
  • <tbody> — Separates data from headers/footers; useful when JavaScript adds or removes rows dynamically.
  • <tfoot> — Shows totals or summary rows (invoice total, grade average) that apply to all body rows.
  • <th scope="col"> — Labels a column (“Price”, “Quantity”).
  • <th scope="row"> — Labels a row (“January”, “Product A”) when the first column is a row header.
  • <colgroup> / <col> — Style or width entire columns (e.g. narrow “ID” column, wide “Description” column) without touching every cell.
Example: Full Semantic Table
Monthly Team Performance Report
Team Tasks Completed Pending Tasks Status
Frontend 42 6 On Track
Backend 39 9 Needs Review
Total 81 15 Overall Good
Do not use tables for page layout. Semantic table tags are for tabular data. For grids and page structure, use CSS Flexbox or Grid instead.

Rowspan and Colspan

rowspan merges cells vertically (across rows), and colspan merges cells horizontally (across columns). These attributes are useful for grouped headings, schedules, and report-style tables.

Example 1: Using colspan for grouped headers
Student Marks Result
Math Science English
Asha 88 91 84 Pass
Rahul 75 80 78 Pass
Example 2: Using rowspan for timetable grouping
Day Time Subject
Monday 10:00 - 11:00 HTML
11:15 - 12:15 CSS
Tuesday 10:00 - 11:00 JavaScript
11:15 - 12:15 Bootstrap
HTML Code:
<tr>
    <th rowspan="2">Monday</th>
    <td>10:00 - 11:00</td>
    <td>HTML</td>
</tr>
<tr>
    <td>11:15 - 12:15</td>
    <td>CSS</td>
</tr>

<tr>
    <th>Student</th>
    <th colspan="3">Marks</th>
</tr>

Responsive Tables

On small screens, wide tables can become difficult to read. A simple approach for responsiveness is to wrap your table in a container that allows horizontal scrolling. Bootstrap’s .table-responsive class does this for you.

Example: Responsive Table Container
Quarter Revenue Expenses Profit
Q1 $50,000 $30,000 $20,000
Q2 $65,000 $38,000 $27,000
HTML Code:
<div class="table-responsive">
    <table class="table">
        ...
    </table>
</div>

Accessible Tables

For accessibility, always relate header cells and data cells clearly.

  • Use <th scope="col"> for column headers.
  • Use <th scope="row"> for row headers when appropriate.
  • Provide a <caption> for context.

Best Practices

  • Use tables only for tabular data, not for page layout.
  • Keep tables simple; avoid overly complex nesting.
  • Use CSS for styling (borders, colors, spacing).
  • Ensure tables are readable on smaller screens (consider responsive patterns).