<div role="region" tabindex="0" aria-label="Our Party" aria-describedby="table-caption">
    <table>
        <caption id="table-caption">Members of the party.</caption>
        <thead>
            <tr>
                <th>Name</th>
                <th>E-mail</th>
                <th>Role</th>
            </tr>
        </thead>

        <tbody>
            <tr>
                <td>Bilbo Baggins</td>
                <td>bilbo.baggins@hotmail.com</td>
                <td>Rogue</td>
            </tr>
            <tr>
                <td>Gandalf the Grey</td>
                <td>gandalf@icloud.com</td>
                <td>Wizard</td>
            </tr>
            <tr>
                <td>Thorin Oakenshield</td>
                <td>oakenshield@gmail.com</td>
                <td>Fighter</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": "Our Party",
  "caption": "Members of the party.",
  "captionSide": "top",
  "columnHeaders": [
    "Name",
    "E-mail",
    "Role"
  ],
  "rowHeaders": [],
  "records": [
    [
      "Bilbo Baggins",
      "bilbo.baggins@hotmail.com",
      "Rogue"
    ],
    [
      "Gandalf the Grey",
      "gandalf@icloud.com",
      "Wizard"
    ],
    [
      "Thorin Oakenshield",
      "oakenshield@gmail.com",
      "Fighter"
    ]
  ]
}

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.