| Heading | Heading |
|---|---|
| Data | Data |
| Data | Data |
| Data | Data |
| Data | Data |
Table
Tables contain facts or figures that are organized in rows and columns.
Also known as: comparison table, data grid, data table, datagrid, grid, HTML table, results table, structured table, table tree, table view
<div class="bolt-table">
<table>
<tr>
<th>Heading</th>
<th>Heading</th>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
</tr>
</table>
</div>
Fit content
Permalink to "Fit content"By default, the table will span the width of its container. For a table that is only as wide as its content, apply the bolt-table-fit-content class.
| Heading | Heading |
|---|---|
| Data | Data |
| Data | Data |
| Data | Data |
| Data | Data |
<div class="bolt-table bolt-table-fit-content">
<table>
<tr>
<th>Heading</th>
<th>Heading</th>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
</tr>
</table>
</div>
Striped rows
Permalink to "Striped rows"Use the bolt-table-striped class to add an alternating background color between rows.
| Heading | Heading |
|---|---|
| Data | Data |
| Data | Data |
| Data | Data |
| Data | Data |
<div class="bolt-table bolt-table-striped">
<table>
<tr>
<th>Heading</th>
<th>Heading</th>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
</tr>
</table>
</div>
Multi-level tables
Permalink to "Multi-level tables"Sub-headings should be given the bolt-table-sub-head class to visually distinguish them from top-level headers. See the table accessibility guidelines for additional information on building complex tables.
| Heading | Heading |
|---|---|
| Sub-heading | |
| Data | Data |
| Data | Data |
| Sub-heading | |
| Data | Data |
| Data | Data |
<div class="bolt-table">
<table>
<thead>
<tr>
<th id="head1grey" scope="col">Heading</th>
<th id="head2grey" scope="col">Heading</th>
</tr>
</thead>
<tbody>
<tr>
<th class="bolt-table-sub-head" id="sub1grey" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1grey sub1grey">Data</td>
<td headers="head2grey sub1grey">Data</td>
</tr>
<tr>
<td headers="head1grey sub1grey">Data</td>
<td headers="head2grey sub1grey">Data</td>
</tr>
<tr>
<th class="bolt-table-sub-head" id="sub2grey" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1grey sub2grey">Data</td>
<td headers="head2grey sub2grey">Data</td>
</tr>
<tr>
<td headers="head1grey sub2grey">Data</td>
<td headers="head2grey sub2grey">Data</td>
</tr>
</tbody>
</table>
</div>
Theme colors
Permalink to "Theme colors " Theme colors adjust with the global theme to preserve a semantic hierarchy of color options, while ensuring minimum contrast ratios.
| Heading | Heading |
|---|---|
| Sub-heading | |
| Data | Data |
| Data | Data |
| Sub-heading | |
| Data | Data |
| Data | Data |
<div class="bolt-table bolt-table-primary">
<table>
<thead>
<tr>
<th id="head1primary" scope="col">Heading</th>
<th id="head2primary" scope="col">Heading</th>
</tr>
</thead>
<tbody>
<tr>
<th class="bolt-table-sub-head" id="sub1primary" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1primary sub1primary">Data</td>
<td headers="head2primary sub1primary">Data</td>
</tr>
<tr>
<td headers="head1primary sub1primary">Data</td>
<td headers="head2primary sub1primary">Data</td>
</tr>
<tr>
<th class="bolt-table-sub-head" id="sub2primary" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1primary sub2primary">Data</td>
<td headers="head2primary sub2primary">Data</td>
</tr>
<tr>
<td headers="head1primary sub2primary">Data</td>
<td headers="head2primary sub2primary">Data</td>
</tr>
</tbody>
</table>
</div>
| Heading | Heading |
|---|---|
| Sub-heading | |
| Data | Data |
| Data | Data |
| Sub-heading | |
| Data | Data |
| Data | Data |
<div class="bolt-table bolt-table-secondary">
<table>
<thead>
<tr>
<th id="head1secondary" scope="col">Heading</th>
<th id="head2secondary" scope="col">Heading</th>
</tr>
</thead>
<tbody>
<tr>
<th class="bolt-table-sub-head" id="sub1secondary" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1secondary sub1secondary">Data</td>
<td headers="head2secondary sub1secondary">Data</td>
</tr>
<tr>
<td headers="head1secondary sub1secondary">Data</td>
<td headers="head2secondary sub1secondary">Data</td>
</tr>
<tr>
<th class="bolt-table-sub-head" id="sub2secondary" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1secondary sub2secondary">Data</td>
<td headers="head2secondary sub2secondary">Data</td>
</tr>
<tr>
<td headers="head1secondary sub2secondary">Data</td>
<td headers="head2secondary sub2secondary">Data</td>
</tr>
</tbody>
</table>
</div>
| Heading | Heading |
|---|---|
| Sub-heading | |
| Data | Data |
| Data | Data |
| Sub-heading | |
| Data | Data |
| Data | Data |
<div class="bolt-table bolt-table-tertiary">
<table>
<thead>
<tr>
<th id="head1tertiary" scope="col">Heading</th>
<th id="head2tertiary" scope="col">Heading</th>
</tr>
</thead>
<tbody>
<tr>
<th class="bolt-table-sub-head" id="sub1tertiary" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1tertiary sub1tertiary">Data</td>
<td headers="head2tertiary sub1tertiary">Data</td>
</tr>
<tr>
<td headers="head1tertiary sub1tertiary">Data</td>
<td headers="head2tertiary sub1tertiary">Data</td>
</tr>
<tr>
<th class="bolt-table-sub-head" id="sub2tertiary" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1tertiary sub2tertiary">Data</td>
<td headers="head2tertiary sub2tertiary">Data</td>
</tr>
<tr>
<td headers="head1tertiary sub2tertiary">Data</td>
<td headers="head2tertiary sub2tertiary">Data</td>
</tr>
</tbody>
</table>
</div>
Future theme table
Permalink to "Future theme table " The default table appearance becomes theme-aware when using future theme, aligning automatically with the active global theme.
| Heading | Heading |
|---|---|
| Sub-heading | |
| Data | Data |
| Data | Data |
| Sub-heading | |
| Data | Data |
| Data | Data |
<html class="bolt-typography bolt-theme--future">
...
<div class="bolt-table">
<table>
<thead>
<tr>
<th id="head1primary" scope="col">Heading</th>
<th id="head2primary" scope="col">Heading</th>
</tr>
</thead>
<tbody>
<tr>
<th class="bolt-table-sub-head" id="sub1primary" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1primary sub1primary">Data</td>
<td headers="head2primary sub1primary">Data</td>
</tr>
<tr>
<td headers="head1primary sub1primary">Data</td>
<td headers="head2primary sub1primary">Data</td>
</tr>
<tr>
<th class="bolt-table-sub-head" id="sub2primary" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1primary sub2primary">Data</td>
<td headers="head2primary sub2primary">Data</td>
</tr>
<tr>
<td headers="head1primary sub2primary">Data</td>
<td headers="head2primary sub2primary">Data</td>
</tr>
</tbody>
</table>
</div>
...
</html>
In Bolt 8, the default table will automatically inherit the active theme appearance. You can opt into this behavior early using future theme.
Static colors
Permalink to "Static colors"In addition to the default grey, the Bolt table is available in five color variations (vibrant blue, dark blue, mint, sea blue, and light blue).
| Heading | Heading |
|---|---|
| Sub-heading | |
| Data | Data |
| Data | Data |
| Sub-heading | |
| Data | Data |
| Data | Data |
<div class="bolt-table bolt-table-vibrantBlue">
<table>
<thead>
<tr>
<th id="head1vibrantblue" scope="col">Heading</th>
<th id="head2vibrantblue" scope="col">Heading</th>
</tr>
</thead>
<tbody>
<tr>
<th class="bolt-table-sub-head" id="sub1vibrantblue" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1vibrantblue sub1vibrantblue">Data</td>
<td headers="head2vibrantblue sub1vibrantblue">Data</td>
</tr>
<tr>
<td headers="head1vibrantblue sub1vibrantblue">Data</td>
<td headers="head2vibrantblue sub1vibrantblue">Data</td>
</tr>
<tr>
<th class="bolt-table-sub-head" id="sub2vibrantblue" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1vibrantblue sub2vibrantblue">Data</td>
<td headers="head2vibrantblue sub2vibrantblue">Data</td>
</tr>
<tr>
<td headers="head1vibrantblue sub2vibrantblue">Data</td>
<td headers="head2vibrantblue sub2vibrantblue">Data</td>
</tr>
</tbody>
</table>
</div>
| Heading | Heading |
|---|---|
| Sub-heading | |
| Data | Data |
| Data | Data |
| Sub-heading | |
| Data | Data |
| Data | Data |
<div class="bolt-table bolt-table-darkBlue">
<table>
<thead>
<tr>
<th id="head1darkblue" scope="col">Heading</th>
<th id="head2darkblue" scope="col">Heading</th>
</tr>
</thead>
<tbody>
<tr>
<th class="bolt-table-sub-head" id="sub1darkblue" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1darkblue sub1darkblue">Data</td>
<td headers="head2darkblue sub1darkblue">Data</td>
</tr>
<tr>
<td headers="head1darkblue sub1darkblue">Data</td>
<td headers="head2darkblue sub1darkblue">Data</td>
</tr>
<tr>
<th class="bolt-table-sub-head" id="sub2darkblue" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1darkblue sub2darkblue">Data</td>
<td headers="head2darkblue sub2darkblue">Data</td>
</tr>
<tr>
<td headers="head1darkblue sub2darkblue">Data</td>
<td headers="head2darkblue sub2darkblue">Data</td>
</tr>
</tbody>
</table>
</div>
| Heading | Heading |
|---|---|
| Sub-heading | |
| Data | Data |
| Data | Data |
| Sub-heading | |
| Data | Data |
| Data | Data |
<div class="bolt-table bolt-table-mint">
<table>
<thead>
<tr>
<th id="head1mint" scope="col">Heading</th>
<th id="head2mint" scope="col">Heading</th>
</tr>
</thead>
<tbody>
<tr>
<th class="bolt-table-sub-head" id="sub1mint" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1mint sub1mint">Data</td>
<td headers="head2mint sub1mint">Data</td>
</tr>
<tr>
<td headers="head1mint sub1mint">Data</td>
<td headers="head2mint sub1mint">Data</td>
</tr>
<tr>
<th class="bolt-table-sub-head" id="sub2mint" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1mint sub2mint">Data</td>
<td headers="head2mint sub2mint">Data</td>
</tr>
<tr>
<td headers="head1mint sub2mint">Data</td>
<td headers="head2mint sub2mint">Data</td>
</tr>
</tbody>
</table>
</div>
| Heading | Heading |
|---|---|
| Sub-heading | |
| Data | Data |
| Data | Data |
| Sub-heading | |
| Data | Data |
| Data | Data |
<div class="bolt-table bolt-table-seaBlue">
<table>
<thead>
<tr>
<th id="head1seablue" scope="col">Heading</th>
<th id="head2seablue" scope="col">Heading</th>
</tr>
</thead>
<tbody>
<tr>
<th class="bolt-table-sub-head" id="sub1seablue" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1seablue sub1seablue">Data</td>
<td headers="head2seablue sub1seablue">Data</td>
</tr>
<tr>
<td headers="head1seablue sub1seablue">Data</td>
<td headers="head2seablue sub1seablue">Data</td>
</tr>
<tr>
<th class="bolt-table-sub-head" id="sub2seablue" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1seablue sub2seablue">Data</td>
<td headers="head2seablue sub2seablue">Data</td>
</tr>
<tr>
<td headers="head1seablue sub2seablue">Data</td>
<td headers="head2seablue sub2seablue">Data</td>
</tr>
</tbody>
</table>
</div>
| Heading | Heading |
|---|---|
| Sub-heading | |
| Data | Data |
| Data | Data |
| Sub-heading | |
| Data | Data |
| Data | Data |
<div class="bolt-table bolt-table-lightBlue">
<table>
<thead>
<tr>
<th id="head1lightblue" scope="col">Heading</th>
<th id="head2lightblue" scope="col">Heading</th>
</tr>
</thead>
<tbody>
<tr>
<th class="bolt-table-sub-head" id="sub1lightblue" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1lightblue sub1lightblue">Data</td>
<td headers="head2lightblue sub1lightblue">Data</td>
</tr>
<tr>
<td headers="head1lightblue sub1lightblue">Data</td>
<td headers="head2lightblue sub1lightblue">Data</td>
</tr>
<tr>
<th class="bolt-table-sub-head" id="sub2lightblue" colspan="2">Sub-heading</th>
</tr>
<tr>
<td headers="head1lightblue sub2lightblue">Data</td>
<td headers="head2lightblue sub2lightblue">Data</td>
</tr>
<tr>
<td headers="head1lightblue sub2lightblue">Data</td>
<td headers="head2lightblue sub2lightblue">Data</td>
</tr>
</tbody>
</table>
</div>
Alignment options
Permalink to "Alignment options"Vertical and horizontal alignment classes can be applied to the entire table, or to individual rows and cells.
| Heading | Heading | Heading |
|---|---|---|
| Data | Data | Data (right aligned) |
| Data | Data | Data (right aligned) |
| Data (bottom aligned) |
Data (bottom aligned) |
Data (right aligned & bottom aligned) |
<div class="bolt-table bolt-table-align-center">
<table>
<tr>
<th>Heading</th>
<th>Heading</th>
<th>Heading</th>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td class="bolt-table-align-right">Data<br>(right aligned)</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td class="bolt-table-align-right">Data<br>(right aligned)</td>
</tr>
<tr class="bolt-table-align-bottom">
<td>Data<br>(bottom aligned)</td>
<td>Data<br>(bottom aligned)</td>
<td class="bolt-table-align-right">Data<br>(right aligned<br>&<br>bottom aligned)</td>
</tr>
</table>
</div>
The Bolt table is created by wrapping a standard HTML table in a container with the bolt-table class.
The following classes may also be applied to the table for styling:
bolt-table-striped: applies an alternating background color to table rows.bolt-table-fit-content: sets the overall table width to the minimum width required by its content. By default, the table will take up 100% of its container.- Table color classes modify the color headings and sub-headings
- Static colors:
bolt-table-vibrantBluebolt-table-darkBluebolt-table-mintbolt-table-seaBlue
- Theme colors:
bolt-table-primarybolt-table-secondarybolt-table-tertiary
- Static colors:
bolt-table-align-top,bolt-table-align-middle,bolt-table-align-bottom: sets the vertical alignment of cell contents for the whole table, or by applying to individual rows or cells.bolt-table-align-left,bolt-table-align-center,bolt-table-align-right: sets the horizontal alignment of cell contents for the whole table, or by applying to individual rows or cells.
For multi-level tables, use the bolt-table-sub-head class on sub-heading <th> elements. For additional information about building complex tables, see the accessibility guidelines.
‑ can prevent text from wrapping onto multiple lines.
General guidelines
Permalink to "General guidelines"- Content should be aligned for easy scanning, reading, and comparison.
- Left-align text or a combination of text and numbers.
- Right-align columns of numbers only, this makes them easier to compare.
- Align header texts with their corresponding content.
- Avoid center-aligning content in Tables.
- Keep headers clear and concise.
- A user should be informed when there is no data to show.
- Include a visual indicator for cells that don't have content (e.g. a dash or "N/A").
- Include a message panel when the entire table is empty.
- Enough space should be allowed for content to account for localization.
- Consider longest and shortest values, including what the database allows.
- There should be a summary row/column to display totals.
- Minimizing the visual styling of Tables helps users focus on the presented information.
Responsiveness
Permalink to "Responsiveness"- A Table should be tested for largest and smallest screen sizes to ensure that it works on both. An alternate display method may be needed for mobile devices. Horizontal scrolling is not recommended but may be necessary for small displays.
Header cells
Permalink to "Header cells"- Column headers should be short.
- Allow for filtering and sorting when comparison is not a priority.
- Multiple heading rows are allowed for higher-level grouping of columns.
Columns
Permalink to "Columns"- The number of columns should be minimal as possible.
- Adapt column widths when necessary.
Cell data
Permalink to "Cell data"- Cell content should be concise.
- Important content may wrap to multiple lines.
- It is preferred to avoid wrapping or truncation of cell content.
When to use
Permalink to "When to use"- To organize and display data, particularly when presenting multiple metrics and categories together.
- To help users navigate a lot of information at once and make it easy to compare data points.
- When all data points are displayed in a flat hierarchy or when content is structured and has the same attributes.
When not to use
Permalink to "When not to use"- Table should not be used for displaying content that doesn't follow a consistent pattern and can't be broken down into columns.
- Table is not a replacement for a spreadsheet application.
- Avoid Table when a more complex display of the data or interactions is required.
- Avoid Table if there will never be enough data to populate at least 2 rows.
- A Table should not be used for an actionable list of items with links to detail pages.
When to use something else
Permalink to "When to use something else"- Use lists or other alternatives when there are columns where cells will usually be empty.
- If the data is easier to understand with grouping and hierarchy, consider alternatives to Table.
- For data with long-form content, consider paragraphs or lists.
- If rows or columns support some kind of user interaction, consider options other than Table.
- When rows and columns are only a means of layout; use Grid instead.
Do
- Align content for easy scanning, reading, and comparison.
- Keep content clear and concise.
- Include a visual indicator for cells without content.
- Use multiple heading rows for higher-level grouping of columns.
- Order rows intuitively.
- Minimize the number of columns.
- Adapt column widths when necessary.
- Keep cell content concise, wrapping where needed.
- Use Pagination to accommodate large datasets.
Don't
- Don't assume that a Table that works on large screens should be set up the same way for small screens.
- Don't use vague labels, leaving users guessing what a row or column is about.
- Don't extensively wrap Table contents in a narrow column.
- Don't use Table for information that has hierarchical relationships.
- Don't repeat or rephrase the title in the page header as the Table title.
- Don't use 'zebra striping' on Tables with fewer than 4 rows.
- Don't overuse color and styling for text in Tables.
- Don't truncate cell content unnecessarily.
Content guidelines
Permalink to "Content guidelines"- Table column headers use sentence case.
- Table column headers should clearly describe what is inside each column.
- Column and row labels should be short so at least two columns can be viewed on a small display.
Accessibility compliance
Permalink to "Accessibility compliance"-
WCAG 2.2 Compliant
-
JAWS 2025 Tested
-
NVDA 2025 Tested
-
VoiceOver Issues found
-
Keyboard Tested
-
aXe Tested
Accessible tables need HTML markup that indicates header cells and data cells and defines their relationship. Assistive technologies use this information to provide context to users.
Header cells must be marked up with <th>, and data cells with <td> to make tables accessible. For more complex tables, explicit associations may be needed using scope, id, and headers attributes.
Quick links
Permalink to "Quick links"- Tables with one header
- Tables with two headers
- Tables with complex headers
- Tables with sticky headers
- Caption
Tables with one row or column header
Permalink to "Tables with one row or column header"
Table with top rows as header cells
Permalink to "Table with top rows as header cells"| Header | Header | Header | Header |
|---|---|---|---|
| Data | Data | Data | Data |
| Data | Data | Data | Data |
<div class="bolt-table">
<table>
<tr>
<th>Header</th>
<th>Header</th>
<th>Header</th>
<th>Header</th>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
</table>
</div>

Table with first columm as header cells
Permalink to "Table with first columm as header cells"| Header | Data | Data | Data |
|---|---|---|---|
| Header | Data | Data | Data |
| Header | Data | Data | Data |
<div class="bolt-table">
<table>
<tr>
<th>Header</th>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<th>Header</th>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<th>Header</th>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
</table>
</div>

Table with ambiguous data
Permalink to "Table with ambiguous data"| Last Name | First Name | City |
|---|---|---|
| Johnson | Alex | Harry |
| Kent | Michael | Powell |
| Harrison | Mason | Celina |
<div class="bolt-table">
<table>
<tr>
<th scope="col">Last Name</th>
<th scope="col">First Name</th>
<th scope="col">City</th>
</tr>
<tr>
<td>Johnson</td>
<td>Alex</td>
<td>Harry</td>
</tr>
<tr>
<td>Kent</td>
<td>Michael</td>
<td>Powell</td>
</tr>
<tr>
<td>Harrison</td>
<td>Mason</td>
<td>Celina</td>
</tr>
</table>
</div>
Tables with two headers
Permalink to "Tables with two headers"Please use <th> element for header cells and the scope attribute to specify direction of each header.
scope="row": header applies to the entire rowscope="col": header applies to the entire columns

Table with header cells in the top row and first column
Permalink to "Table with header cells in the top row and first column"| Fund A | Fund B | Fund C | |
|---|---|---|---|
| Data 1 | Name 1 | Name 2 | Name 3 |
| Date 2 | Name 4 | Name 5 | Name 6 |
<div class="bolt-table">
<table>
<tr>
<th></th>
<th scope="col">Fund A</th>
<th scope="col">Fund B</th>
<th scope="col">Fund C</th>
</tr>
<tr>
<th scope="row">Data 1</th>
<td>Name 1</td>
<td>Name 2</td>
<td>Name 3</td>
</tr>
<tr>
<th scope="row">Date 2</th>
<td>Name 4</td>
<td>Name 5</td>
<td>Name 6</td>
</tr>
</table>
</div>

Table with header cells in the 2nd row and first column
Permalink to "Table with header cells in the 2nd row and first column"| ID | Name | January | February |
|---|---|---|---|
| 10 | Name 1 | 5 | 2 |
| 3 | Name 2 | 4 | 7 |
| 1 | Name 3 | 8 | 5 |
<div class="bolt-table">
<table>
<tr>
<th scope="col">ID</th>
<th scope="col">Name</th>
<th scope="col">January</th>
<th scope="col">February</th>
</tr>
<tr>
<td>10</td>
<th scope="row" class="bolt-table-sub-head">Name 1</th>
<td>5</td>
<td>2</td>
</tr>
...
</table>
</div>
Tables with complex headers
Permalink to "Tables with complex headers"- It require a unique
idon eachthheader. - Each data cell needs a
headersattribute to associate which header should be associated with the data cell.

Table with two tier headers
Permalink to "Table with two tier headers"| Average Annual Return (%) | ||||
|---|---|---|---|---|
| 1YR | 2YR | 3YR | 4YR | |
| Fund ABC | 2.4 | 3.3 | 4.5 | 5.9 |
| Fund XYZ | 3.5 | 4.9 | 5.2 | 6.5 |
<div class="bolt-table">
<table>
<tr>
<th rowspan="2"></th>
<th colspan="4" id="avr">Average Annual Return (%)</th>
</tr>
<tr>
<th scope="col" id="year1">1YR</th>
<th scope="col" id="year2">2YR</th>
<th scope="col" id="year3">3YR</th>
<th scope="col" id="year4">4YR</th>
</tr>
<tr>
<th scope="row" id="fund1" class="bolt-table-sub-head">Fund ABC</th>
<td headers="avr year1 fund1">2.4</td>
<td headers="avr year2 fund1">3.3</td>
<td headers="avr year3 fund1">4.5</td>
<td headers="avr year4 fund1">5.9</td>
</tr>
<tr>
<th scope="row" id="fund2" class="bolt-table-sub-head" >Fund XYZ</th>
<td headers="avr year1 fund2">3.5</td>
<td headers="avr year2 fund2">4.9</td>
<td headers="avr year3 fund2">5.2</td>
<td headers="avr year4 fund2">6.5</td>
</tr>
</table>
</div>

Table with multiple column headers in each column
Permalink to "Table with multiple column headers in each column"<div class="bolt-table">
<table class="accessibility-docs hide-caption">
<tbody>
<tr>
<th> </th>
<th id="co1">Header 1</th>
<th id="co2">Header 2</th>
</tr>
<tr>
<th id="c1" class="bolt-table-sub-head">Contact</th>
<td headers="co1 c1">Data</td>
<td headers="co2 c1">Data</td>
</tr>
<tr>
<th id="p1" class="bolt-table-sub-head">Position</th>
<td headers="co1 p1">Data</td>
<td headers="co2 p1">Data</td>
</tr>
<tr>
<th id="e1" class="bolt-table-sub-head">Email</th>
<td headers="co1 e1">Data</td>
<td headers="co2 e1">Data</td>
</tr>
<tr>
<th> </th>
<th id="co3">Header 3</th>
<th id="co4">Header 4</th>
</tr>
<tr>
<th id="c2" class="bolt-table-sub-head">Contact</th>
<td headers="co3 c2">Data</td>
<td headers="co4 c2">Data</td>
</tr>
<tr>
<th id="p2" class="bolt-table-sub-head">Position</th>
<td headers="co3 p2">Data</td>
<td headers="co4 p2">Data</td>
</tr>
<tr>
<th id="e2" class="bolt-table-sub-head">Email</th>
<td headers="co3 e2">Data</td>
<td headers="co4 e2">Data</td>
</tr>
</tbody>
</table>
</div>

Table with multiple headers related to each data cell
Permalink to "Table with multiple headers related to each data cell"Example table with <caption> information is visible to user.
| Header 1 | Header 2 | Header 3 | Header 4 | |
|---|---|---|---|---|
| Sub header 1 | ||||
| Data 1 | 11 | 20 | 25 | 23 |
| Data 2 | - | 43 | 52 | 32 |
| Data 3 | - | 13 | 15 | 40 |
| Sub header 2 | ||||
| Data 1 | 13 | 21 | 22 | 3 |
| Data 2 | - | 23 | 43 | 30 |
| Data 3 | - | 16 | 32 | 40 |
<div class="bolt-table">
<table class="bolt-table">
<caption>Data performance caption
<span>Column one has data, other columns show variety of supporting data.</span>
</caption>
<thead>
<tr>
<th> </th>
<th id="header11" scope="col">
Header 1
</th>
<th id="header12" scope="col">
Header 2
</th>
<th id="header13" scope="col">
Header 3
</th>
<th id="header14" scope="col">
Header 4
</th>
</tr>
</thead>
<tbody>
<tr>
<th id="subheader11" colspan="5">
Sub header 1
</th>
</tr>
<tr>
<th headers="subheader11" id="subid11" class="bolt-table-sub-head" >
Data 1
</th>
<td headers="header11 subheader11 subid11">
11
</td>
<td headers="header12 subheader11 subid11">
20
</td>
<td headers="header13 subheader11 subid11">
25
</td>
<td headers="header14 subheader11 subid11">
23
</td>
</tr>
<tr>
<th headers="subheader11" id="subid12" class="bolt-table-sub-head">
Data 2
</th>
<td headers="header11 subheader11 subid12 ">
-
</td>
<td headers="header12 subheader11 subid12 ">
43
</td>
<td headers="header13 subheader11 subid12 ">
52
</td>
<td headers="header14 subheader11 subid12">
32
</td>
</tr>
<tr>
<th headers="subheader11" id="subid13" class="bolt-table-sub-head">
Data 3
</th>
<td headers="header11 subheader11 subid13 ">
-
</td>
<td headers="header12 subheader11 subid13 ">
13
</td>
<td headers="header13 subheader11 subid13 ">
15
</td>
<td headers="header14 subheader11 subid13 ">
40
</td>
</tr>
<tr>
<th id="subheader22" colspan="5" class="header">
Sub header 2
</th>
</tr>
<tr>
<th headers="subheader22" id="subid21" class="bolt-table-sub-head" >
Data 1
</th>
<td headers="header11 subheader22 subid21 ">
13
</td>
<td headers="header12 subheader22 subid21 ">
21
</td>
<td headers="header13 subheader22 subid21 ">
22
</td>
<td headers="header14 subheader22 subid21 ">
3
</td>
</tr>
<tr>
<th headers="subheader22" id="subid22" class="bolt-table-sub-head" >
Data 2
</th>
<td headers="header11 subheader22 subid22 ">
-
</td>
<td headers="header12 subheader22 subid22 ">
23
</td>
<td headers="header13 subheader22 subid22 ">
43
</td>
<td headers="header14 subheader22 subid22 ">
30
</td>
</tr>
<tr>
<th headers="subheader22" id="subid23" class="bolt-table-sub-head" >
Data 3
</th>
<td headers="header11 subheader22 subid23 ">
-
</td>
<td headers="header12 subheader22 subid23 ">
16
</td>
<td headers="header13 subheader22 subid23 ">
32
</td>
<td headers="header14 subheader22 subid23 ">
40
</td>
</tr>
</tbody>
</table>
</div>
Tables with sticky headers
Permalink to "Tables with sticky headers"
A table with sticky headers keeps column headers visible while scrolling so users—especially those with visual or cognitive disabilities—can maintain context, and it must also include proper table markup (such as <th> with scope attributes and clear header–cell relationships) so screen reader users can correctly understand and navigate the data structure.
| Transaction ID | Date | Description | Category | Amount (USD) | Balance (USD) |
|---|---|---|---|---|---|
| 1001 | Mar 01 | Payroll Deposit | Income | +3,200.00 | 8,450.25 |
| 1002 | Mar 02 | Grocery Store | Food | -84.37 | 8,365.88 |
| 1003 | Mar 03 | Utility Bill Payment | Utilities | -120.50 | 8,245.38 |
| 1004 | Mar 04 | Online Subscription | Entertainment | -12.99 | 8,232.39 |
| 1005 | Mar 05 | Gas Station | Transportation | -45.20 | 8,187.19 |
| 1006 | Mar 06 | Coffee Shop | Food | -6.75 | 8,180.44 |
| 1007 | Mar 07 | Stock Dividend | Investment | +48.30 | 8,228.74 |
| 1008 | Mar 08 | Restaurant | Food | -63.90 | 8,164.84 |
| 1009 | Mar 09 | Gym Membership | Health | -29.99 | 8,134.85 |
| 1010 | Mar 10 | Transfer to Savings | Transfer | -500.00 | 7,634.85 |
| 1011 | Mar 11 | Freelance Payment | Income | +750.00 | 8,384.85 |
| 1012 | Mar 12 | Pharmacy | Health | -24.15 | 8,360.70 |
| 1013 | Mar 13 | Movie Tickets | Entertainment | -27.00 | 8,333.70 |
| 1014 | Mar 14 | Internet Bill | Utilities | -79.99 | 8,253.71 |
| 1015 | Mar 15 | Interest Earned | Bank Interest | +3.42 | 8,257.13 |
<!-- Example of sticky header styles -->
<style>
.custom-table-sticky {
overflow: visible;
display: table;
width: stretch;
thead {
position: sticky;
top: -1px;
box-shadow: 0 4px 10px -4px var(--bolt-theme-shadow);
}
}
</style>
<!-- Example markup with custom class for styling -->
<div class="bolt-table custom-table-sticky">
<table>
<caption>Recent Account Transaction History</caption>
<thead>
<tr>
<th scope="col">Transaction ID</th>
<th scope="col">Date</th>
<th scope="col">Description</th>
<th scope="col">Category</th>
<th scope="col">Amount (USD)</th>
<th scope="col">Balance (USD)</th>
</tr>
</thead>
<tbody>
<tr>
<td>1001</td>
<td>Mar 01</td>
<td>Payroll Deposit</td>
<td>Income</td>
<td>+3,200.00</td>
<td>8,450.25</td>
</tr>
<tr>
<td>1002</td>
<td>Mar 02</td>
<td>Grocery Store</td>
<td>Food</td>
<td>-84.37</td>
<td>8,365.88</td>
</tr>
<tr>
<td>1003</td>
<td>Mar 03</td>
<td>Utility Bill Payment</td>
<td>Utilities</td>
<td>-120.50</td>
<td>8,245.38</td>
</tr>
<tr>
<td>1004</td>
<td>Mar 04</td>
<td>Online Subscription</td>
<td>Entertainment</td>
<td>-12.99</td>
<td>8,232.39</td>
</tr>
<tr>
<td>1005</td>
<td>Mar 05</td>
<td>Gas Station</td>
<td>Transportation</td>
<td>-45.20</td>
<td>8,187.19</td>
</tr>
<tr>
<td>1006</td>
<td>Mar 06</td>
<td>Coffee Shop</td>
<td>Food</td>
<td>-6.75</td>
<td>8,180.44</td>
</tr>
<tr>
<td>1007</td>
<td>Mar 07</td>
<td>Stock Dividend</td>
<td>Investment</td>
<td>+48.30</td>
<td>8,228.74</td>
</tr>
<tr>
<td>1008</td>
<td>Mar 08</td>
<td>Restaurant</td>
<td>Food</td>
<td>-63.90</td>
<td>8,164.84</td>
</tr>
<tr>
<td>1009</td>
<td>Mar 09</td>
<td>Gym Membership</td>
<td>Health</td>
<td>-29.99</td>
<td>8,134.85</td>
</tr>
<tr>
<td>1010</td>
<td>Mar 10</td>
<td>Transfer to Savings</td>
<td>Transfer</td>
<td>-500.00</td>
<td>7,634.85</td>
</tr>
<tr>
<td>1011</td>
<td>Mar 11</td>
<td>Freelance Payment</td>
<td>Income</td>
<td>+750.00</td>
<td>8,384.85</td>
</tr>
<tr>
<td>1012</td>
<td>Mar 12</td>
<td>Pharmacy</td>
<td>Health</td>
<td>-24.15</td>
<td>8,360.70</td>
</tr>
<tr>
<td>1013</td>
<td>Mar 13</td>
<td>Movie Tickets</td>
<td>Entertainment</td>
<td>-27.00</td>
<td>8,333.70</td>
</tr>
<tr>
<td>1014</td>
<td>Mar 14</td>
<td>Internet Bill</td>
<td>Utilities</td>
<td>-79.99</td>
<td>8,253.71</td>
</tr>
<tr>
<td>1015</td>
<td>Mar 15</td>
<td>Interest Earned</td>
<td>Bank Interest</td>
<td>+3.42</td>
<td>8,257.13</td>
</tr>
</tbody>
</table>
</div>
Caption
Permalink to "Caption"It's an information that recommended to be implemented to help users find a table and understand what it's about. You can hide caption from screen by using CSS property visibility:hidden but still accessible to keyboard users.
- For example :
<div class="bolt-table"> <table class="bolt-table"> <caption> Data performance caption <span> Column one has data, other columns show variety of supporting data. </span> </caption> </table> </div> - And CSS code :
caption { visibility: hidden; }
Accessibility issues
Permalink to "Accessibility issues"VoiceOver
Permalink to "VoiceOver"- The use of headers/id attributes on complex tables is not supported by Apple, i.e. these tables remain inaccessible to VoiceOver users on iOS and MacOS platforms.
All Bolt components have gone through accessibility testing, but please keep our accessibility guidelines in mind.