HTML5 Mastery: The Complete Web Foundation
HomeInsightsCoursesHTMLTable Structure (table, tr, td, th)
Tables & Data

Table Structure (table, tr, td, th)

Master HTML tables for organizing tabular data. Learn table structure, semantic elements, and how to create accessible data tables.

When to Use Tables

✅ Use Tables For:

  • Tabular data (spreadsheet-like)
  • Pricing comparisons
  • Schedules and calendars
  • Statistics and results
  • Data reports

❌ Don't Use Tables For:

  • Page layout (use CSS Grid/Flexbox)
  • Navigation menus
  • Image galleries
  • Any non-tabular content

Basic Table Structure

HTML
<table>
    <tr>  <!-- Table Row --&gt;
        <th>Header 1</th>  <!-- Table Header --&gt;
        <th>Header 2</th>
        <th>Header 3</th>
    </tr>
    <tr>
        <td>Data 1</td>  <!-- Table Data --&gt;
        <td>Data 2</td>
        <td>Data 3</td>
    </tr>
    <tr>
        <td>Data 4</td>
        <td>Data 5</td>
        <td>Data 6</td>
    </tr>
</table>

Key Elements:

  • <table> - Container for the entire table
  • <tr> - Table row (horizontal)
  • <th> - Table header cell (bold, centered by default)
  • <td> - Table data cell

Complete Table Example

HTML
<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>Bob Johnson</td>
        <td>45</td>
        <td>Chicago</td>
    </tr>
</table>

Table Sections

Organize tables into semantic sections for better structure and styling:

HTML
<table>
    <thead>  <!-- Table Head --&gt;
        <tr>
            <th>Product</th>
            <th>Price</th>
            <th>Stock</th>
        </tr>
    </thead>
    
    <tbody>  <!-- Table Body --&gt;
        <tr>
            <td>Laptop</td>
            <td>$999</td>
            <td>15</td>
        </tr>
        <tr>
            <td>Mouse</td>
            <td>$25</td>
            <td>150</td>
        </tr>
        <tr>
            <td>Keyboard</td>
            <td>$75</td>
            <td>80</td>
        </tr>
    </tbody>
    
    <tfoot>  <!-- Table Footer --&gt;
        <tr>
            <th>Total Items</th>
            <td colspan="2">245</td>
        </tr>
    </tfoot>
</table>

Benefits of Sections:

  • Semantic structure for accessibility
  • Easier CSS targeting
  • Header/footer can repeat on printed pages
  • Better for screen readers

Table Caption

Provide a title/description for the table:

HTML
<table>
    <caption>Monthly Sales Report - Q4 2024</caption>
    <thead>
        <tr>
            <th>Month</th>
            <th>Sales</th>
            <th>Growth</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>October</td>
            <td>$45,000</td>
            <td>+12%</td>
        </tr>
        <tr>
            <td>November</td>
            <td>$52,000</td>
            <td>+15%</td>
        </tr>
        <tr>
            <td>December</td>
            <td>$68,000</td>
            <td>+31%</td>
        </tr>
    </tbody>
</table>

<!-- Caption styling --&gt;
<style>
caption {
    font-weight: bold;
    font-size: 1.2em;
    margin-bottom: 0.5em;
    caption-side: top; /* or bottom */
}
</style>

Table Headers (Scope)

Use scope attribute to clarify header relationships:

HTML
<table>
    <thead>
        <tr>
            <th scope="col">Product</th>
            <th scope="col">Q1</th>
            <th scope="col">Q2</th>
            <th scope="col">Q3</th>
            <th scope="col">Q4</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th scope="row">Laptops</th>
            <td>150</td>
            <td>180</td>
            <td>210</td>
            <td>190</td>
        </tr>
        <tr>
            <th scope="row">Tablets</th>
            <td>90</td>
            <td>95</td>
            <td>110</td>
            <td>105</td>
        </tr>
    </tbody>
</table>

<!-- scope values: --&gt;
<!-- col: Header for column --&gt;
<!-- row: Header for row --&gt;
<!-- colgroup: Header for group of columns --&gt;
<!-- rowgroup: Header for group of rows --&gt;

Styling Tables

Basic Styling

HTML
<style>
table {
    border-collapse: collapse; /* Removes space between borders */
    width: 100%;
    max-width: 800px;
    margin: 20px auto;
}

th, td {
    border: 1px solid #ddd;
    padding: 12px;
    text-align: left;
}

th {
    background-color: #4CAF50;
    color: white;
    font-weight: bold;
}

tr:nth-child(even) {
    background-color: #f2f2f2; /* Zebra striping */
}

tr:hover {
    background-color: #ddd; /* Highlight on hover */
}
</style>

Border Styles

CSS
/* Collapsed borders (default recommended) */
table {
    border-collapse: collapse;
}

/* Separated borders */
table {
    border-collapse: separate;
    border-spacing: 5px; /* Space between cells */
}

/* No borders */
table {
    border: none;
}
th, td {
    border: none;
}

/* Only horizontal borders */
th, td {
    border-top: 1px solid #ddd;
    border-bottom: 1px solid #ddd;
}

/* Only vertical borders */
th, td {
    border-left: 1px solid #ddd;
    border-right: 1px solid #ddd;
}

Responsive Tables

Method 1: Horizontal Scroll

HTML
<div class="table-container">
    <table>
        <!-- Table content --&gt;
    </table>
</div>

<style>
.table-container {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch; /* Smooth scrolling on iOS */
}

table {
    min-width: 600px; /* Minimum table width */
}
</style>

Method 2: Stacked on Mobile

HTML
<style>
@media screen and (max-width: 600px) {
    table, thead, tbody, th, td, tr {
        display: block;
    }
    
    thead tr {
        display: none; /* Hide header row */
    }
    
    tr {
        margin-bottom: 15px;
        border: 1px solid #ddd;
    }
    
    td {
        text-align: right;
        padding-left: 50%;
        position: relative;
    }
    
    td::before {
        content: attr(data-label);
        position: absolute;
        left: 10px;
        font-weight: bold;
    }
}
</style>

<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Email</th>
            <th>Phone</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td data-label="Name">John Doe</td>
            <td data-label="Email">john@example.com</td>
            <td data-label="Phone">555-0100</td>
        </tr>
    </tbody>
</table>

Accessibility

Accessible Table Checklist:

  • ✅ Use <caption> for table title
  • ✅ Use <th> for headers (not <td>)
  • ✅ Add scope attribute to headers
  • ✅ Use <thead>, <tbody>, <tfoot>
  • ✅ Provide summary for complex tables
  • ✅ Ensure sufficient color contrast
  • ✅ Don't rely on color alone

Complex Table with IDs

HTML
<table>
    <caption>Sales by Region and Product</caption>
    <thead>
        <tr>
            <th id="region">Region</th>
            <th id="product">Product</th>
            <th id="sales">Sales</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td headers="region">North</td>
            <td headers="product">Laptops</td>
            <td headers="sales">$50,000</td>
        </tr>
    </tbody>
</table>

Best Practices

✅ Do

  • Use tables for tabular data only
  • Include caption and headers
  • Use scope attribute
  • Use thead, tbody, tfoot
  • Make tables responsive
  • Style for readability
  • Test with screen readers
  • Use border-collapse: collapse

❌ Don't

  • Use tables for layout
  • Forget accessibility
  • Make tables too wide
  • Use only for visual design
  • Forget mobile users
  • Use <td> for headers
  • Nest tables unnecessarily
  • Forget caption element

Complete Example

HTML
<table>
    <caption>Employee Directory - IT Department</caption>
    <thead>
        <tr>
            <th scope="col">Name</th>
            <th scope="col">Position</th>
            <th scope="col">Email</th>
            <th scope="col">Extension</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th scope="row">Alice Johnson</th>
            <td>Senior Developer</td>
            <td>alice@company.com</td>
            <td>x4501</td>
        </tr>
        <tr>
            <th scope="row">Bob Smith</th>
            <td>DevOps Engineer</td>
            <td>bob@company.com</td>
            <td>x4502</td>
        </tr>
        <tr>
            <th scope="row">Carol White</th>
            <td>QA Manager</td>
            <td>carol@company.com</td>
            <td>x4503</td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <th scope="row" colspan="3">Total Employees</th>
            <td>3</td>
        </tr>
    </tfoot>
</table>

<style>
table {
    border-collapse: collapse;
    width: 100%;
    max-width: 900px;
    margin: 20px auto;
    font-family: Arial, sans-serif;
}

caption {
    font-size: 1.5em;
    font-weight: bold;
    margin-bottom: 10px;
    color: #333;
}

thead {
    background-color: #2c3e50;
    color: white;
}

th, td {
    padding: 12px 15px;
    text-align: left;
    border: 1px solid #ddd;
}

tbody tr:nth-child(even) {
    background-color: #f8f9fa;
}

tbody tr:hover {
    background-color: #e9ecef;
}

tfoot {
    font-weight: bold;
    background-color: #ecf0f1;
}

@media screen and (max-width: 600px) {
    table {
        font-size: 14px;
    }
    
    th, td {
        padding: 8px;
    }
}
</style>

What's Next?

Learn advanced table features including colspan, rowspan, and column groups.