<div role="region" tabindex="0" aria-label="Q1 Results" aria-describedby="table-caption">
    <table>
        <caption id="table-caption">First quarter revenue and expenses.</caption>
        <thead>
            <tr>
                <th></th>
                <th>Revenue</th>
                <th>Expenses</th>
                <th>Net Income</th>
            </tr>
        </thead>

        <tbody>
            <tr>
                <th scope="row">January</th>
                <td>1800.00</td>
                <td>1375.00</td>
                <td>425.00</td>
            </tr>
            <tr>
                <th scope="row">February</th>
                <td>2100.00</td>
                <td>1550.00</td>
                <td>550.00</td>
            </tr>
            <tr>
                <th scope="row">March</th>
                <td>2250.00</td>
                <td>1375.00</td>
                <td>875.00</td>
            </tr>
        </tbody>
    </table>
</div>
<div role="region" tabindex="0" aria-label="{{ label }}" aria-describedby="table-caption">
    <table{% if captionSide === 'bottom'%} data-caption="bottom"{% endif %}>
        {% if caption -%}
        <caption id="table-caption">{{ caption }}</caption>
        {%- endif -%}
        {% if columnHeaders.length > 0 %}
        <thead>
            <tr>
                {% for header in columnHeaders -%}
                <th>{{ header }}</th>
                {%- endfor %}
            </tr>
        </thead>
        {% endif %}
        <tbody>
            {% for record in records -%}
            <tr>
                {%- if rowHeaders[loop.index0] %}
                <th scope="row">{{ rowHeaders[loop.index0] }}</th>
                {%- endif %}
                {% for column in record -%}
                <td>{{ column }}</td>
                {%- endfor %}
            </tr>
            {%- endfor %}
        </tbody>
    </table>
</div>
{
  "label": "Q1 Results",
  "caption": "First quarter revenue and expenses.",
  "captionSide": "top",
  "columnHeaders": [
    "",
    "Revenue",
    "Expenses",
    "Net Income"
  ],
  "rowHeaders": [
    "January",
    "February",
    "March"
  ],
  "records": [
    [
      "1800.00",
      "1375.00",
      "425.00"
    ],
    [
      "2100.00",
      "1550.00",
      "550.00"
    ],
    [
      "2250.00",
      "1375.00",
      "875.00"
    ]
  ]
}

Table

The <table> element supports an optional <caption> as well as column headers, row headers, or both. It has a responsive layout using the technique described by Adrian Roselli in his blog post “Under-Engineered Responsive Tables”.

By default, the table’s caption appears at the top of the table. If the caption should appear at the bottom of the table, the table can be given a data-caption attribute of bottom.