thead

The thead element groups the header row(s) of a table. It defines the column headers and is essential for table accessibility and proper structure.

Description

The <thead> element contains one or more <tr> elements that define the header row(s) of a table. It must appear after any <caption> or <colgroup> elements and before <tbody> and <tfoot>.

Vanilla Breeze styles thead with a raised background color and a thicker bottom border to visually separate headers from data rows.

When to Use

  • Every data table: All tables with meaningful data should have thead to define column headers
  • Multiple header rows: When columns have grouped headers or sub-headers
  • Printed tables: Headers repeat on each page when printing long tables
  • Sticky headers: Enables CSS position: sticky for headers that remain visible while scrolling

Basic Example

A thead typically contains a single row with <th> elements.

Employee Directory
Name Department Location Email
Alice Johnson Engineering New York alice@example.com
Bob Smith Design San Francisco bob@example.com
Carol Williams Marketing Chicago carol@example.com
<table> <caption>Employee Directory</caption> <thead> <tr> <th scope="col">Name</th> <th scope="col">Department</th> <th scope="col">Location</th> <th scope="col">Email</th> </tr> </thead> <tbody> <!-- Data rows --> </tbody> </table>

Multiple Header Rows

Use multiple rows in thead for grouped or hierarchical headers.

Quarterly Performance by Region
Region Q1 Q2
Revenue Expenses Revenue Expenses
North $45,000 $32,000 $52,000 $35,000
South $38,000 $28,000 $41,000 $30,000
East $55,000 $40,000 $62,000 $45,000
<thead> <tr> <th scope="col" rowspan="2">Region</th> <th scope="colgroup" colspan="2">Q1</th> <th scope="colgroup" colspan="2">Q2</th> </tr> <tr> <th scope="col" data-numeric>Revenue</th> <th scope="col" data-numeric>Expenses</th> <th scope="col" data-numeric>Revenue</th> <th scope="col" data-numeric>Expenses</th> </tr> </thead>

Sticky Headers

The thead element enables sticky positioning for headers that remain visible while scrolling through long tables.

Scrollable Table with Sticky Header
ID Product Price
001 Widget A $19.99
002 Widget B $24.99
003 Widget C $29.99
004 Widget D $34.99
005 Widget E $39.99
006 Widget F $44.99
007 Widget G $49.99
008 Widget H $54.99
<div style="max-block-size: 300px; overflow-y: auto;"> <table> <thead style="position: sticky; inset-block-start: 0;"> <tr> <th scope="col">ID</th> <th scope="col">Product</th> <th scope="col" data-numeric>Price</th> </tr> </thead> <tbody> <!-- Many rows --> </tbody> </table> </div>

Accessibility

  • Structural grouping: Helps assistive technologies distinguish header rows from data rows
  • Use <th> with scope: Always use <th scope="col"> for column headers inside thead
  • Screen reader navigation: Users can navigate directly to the header section of a table
  • Repeated headers: When printing, thead content can repeat on each page

Scope Values for thead

Scope Value Use in thead Description
col Common Header applies to all cells in the column
colgroup Grouped headers Header applies to multiple columns (use with colspan)
row Rare Generally not used in thead

Styling

Vanilla Breeze applies these styles to th elements within thead:

Property Value Purpose
background var(--color-surface-raised) Subtle background to distinguish from data
font-weight 600 Semi-bold for emphasis
border-block-end var(--border-width-medium) Thicker border separating header from body

Related Elements

  • <table> - Parent container
  • <tbody> - Data row group (follows thead)
  • <tfoot> - Footer row group
  • <tr> - Table rows within thead
  • <th> - Header cells (always use in thead)