# Data or header cells must not be used to give caption to a data table.

> Canonical HTML version: https://rocketvalidator.com/accessibility-validation/axe/4.11/table-fake-caption
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

When a data table needs a visible title, developers sometimes create a row at the top of the table containing a single cell that spans all columns using the `colspan` attribute. While this may look like a caption visually, it is semantically incorrect. Screen readers treat it as a regular data or header cell, not as a table title. This means users who rely on assistive technologies — particularly people who are blind or deafblind — won't hear the table's purpose announced as a caption. Instead, they'll encounter what appears to be just another cell of data, making it harder to understand the table's context and contents.

HTML provides the `<caption>` element specifically for this purpose. When a screen reader encounters a `<table>` with a `<caption>`, it announces the caption text as the table's name. This gives users immediate context about what the table contains before they start navigating rows and columns. Without a proper `<caption>`, users must guess the purpose of the table from its data alone.

## Related WCAG Success Criteria

This rule relates to **WCAG 2.1 Success Criterion 1.3.1: Info and Relationships (Level A)**, which requires that information, structure, and relationships conveyed through presentation are programmatically determinable. A fake caption created with `colspan` conveys a relationship visually (this text is the title of this table) but fails to communicate that relationship programmatically.

It also applies to **Section 508** guidelines requiring that row and column headers be identified for data tables, and that markup be used to properly associate data cells and header cells.

## How to Fix It

1. **Remove the fake caption row** — delete the `<tr>` containing the cell with a `colspan` attribute that serves as a visual caption.
2. **Add a `<caption>` element** — place a `<caption>` element as the first child of the `<table>` element, containing the table's title text.
3. **Style as needed** — if you need the caption to look a certain way, apply CSS to the `<caption>` element rather than reverting to a `colspan`-based approach.

## Examples

### Incorrect: Using `colspan` to fake a caption

This approach creates a visual title but is not recognized as a caption by assistive technologies.

```html
<table>
  <tr>
    <td colspan="4"><strong>Quarterly Sales Report</strong></td>
  </tr>
  <tr>
    <th scope="col">Region</th>
    <th scope="col">Q1</th>
    <th scope="col">Q2</th>
    <th scope="col">Q3</th>
  </tr>
  <tr>
    <th scope="row">North</th>
    <td>$12,000</td>
    <td>$15,000</td>
    <td>$13,500</td>
  </tr>
</table>
```

### Correct: Using the `<caption>` element

The `<caption>` element gives the table a programmatically associated name that screen readers announce automatically.

```html
<table>
  <caption>Quarterly Sales Report</caption>
  <thead>
    <tr>
      <th scope="col">Region</th>
      <th scope="col">Q1</th>
      <th scope="col">Q2</th>
      <th scope="col">Q3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">North</th>
      <td>$12,000</td>
      <td>$15,000</td>
      <td>$13,500</td>
    </tr>
  </tbody>
</table>
```

### Correct: Styled `<caption>` element

If you need the caption to match a specific visual design, style it with CSS rather than using table cells.

```html
<style>
  table.data caption {
    font-size: 1.2em;
    font-weight: bold;
    text-align: left;
    padding: 8px 0;
  }
</style>

<table class="data">
  <caption>Greensprings Running Club Personal Bests</caption>
  <thead>
    <tr>
      <th scope="col">Name</th>
      <th scope="col">1 Mile</th>
      <th scope="col">5 km</th>
      <th scope="col">10 km</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Mary</th>
      <td>8:32</td>
      <td>28:04</td>
      <td>1:01:16</td>
    </tr>
    <tr>
      <th scope="row">Betsy</th>
      <td>7:43</td>
      <td>26:47</td>
      <td>55:38</td>
    </tr>
  </tbody>
</table>
```

## What This Rule Checks

The `table-fake-caption` rule inspects data tables for `<td>` or `<th>` cells that use a `colspan` attribute spanning all columns, which suggests the cell is being used as a visual caption. If such a pattern is detected and no proper `<caption>` element is present, the rule flags the table as a violation.
