Table
Preview Available in release assets
Give native data tables readable cell spacing and row rules, and let a wide table scroll inside its own labelled region instead of widening the page.
Table primary example
<div class="thin-table-wrap" tabindex="0" role="region" aria-labelledby="orders-caption">
<table class="thin-table">
<caption id="orders-caption">Recent orders</caption>
<thead>
<tr>
<th scope="col">Order</th>
<th scope="col">Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>1024</td>
<td>$64.00</td>
</tr>
</tbody>
</table>
</div>Show code
<div class="thin-table-wrap" tabindex="0" role="region" aria-labelledby="orders-caption">
<table class="thin-table">
<caption id="orders-caption">Recent orders</caption>
<thead>
<tr>
<th scope="col">Order</th>
<th scope="col">Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>1024</td>
<td>$64.00</td>
</tr>
</tbody>
</table>
</div>Variant gallery
Each authored example uses the production assets and includes copyable markup.
Simple table
Row rules and spacing apply to native cells.
<table class="thin-table" style="--thin-table-min-size: 0">
<caption>Plans</caption>
<thead>
<tr>
<th scope="col">Plan</th>
<th scope="col">Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>Starter</td>
<td>$0</td>
</tr>
<tr>
<td>Team</td>
<td>$12</td>
</tr>
</tbody>
</table>Show code
<table class="thin-table" style="--thin-table-min-size: 0">
<caption>Plans</caption>
<thead>
<tr>
<th scope="col">Plan</th>
<th scope="col">Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>Starter</td>
<td>$0</td>
</tr>
<tr>
<td>Team</td>
<td>$12</td>
</tr>
</tbody>
</table>Scrolling wrapper with a custom minimum
Below its minimum size the table scrolls inside the region.
<div class="thin-table-wrap" tabindex="0" role="region" aria-labelledby="usage-caption">
<table class="thin-table" style="--thin-table-min-size: 48rem">
<caption id="usage-caption">Usage by region</caption>
<thead>
<tr>
<th scope="col">Region</th>
<th scope="col">Requests</th>
<th scope="col">Errors</th>
<th scope="col">Latency</th>
</tr>
</thead>
<tbody>
<tr>
<td>Europe</td>
<td>48,210</td>
<td>12</td>
<td>84 ms</td>
</tr>
</tbody>
</table>
</div>Show code
<div class="thin-table-wrap" tabindex="0" role="region" aria-labelledby="usage-caption">
<table class="thin-table" style="--thin-table-min-size: 48rem">
<caption id="usage-caption">Usage by region</caption>
<thead>
<tr>
<th scope="col">Region</th>
<th scope="col">Requests</th>
<th scope="col">Errors</th>
<th scope="col">Latency</th>
</tr>
</thead>
<tbody>
<tr>
<td>Europe</td>
<td>48,210</td>
<td>12</td>
<td>84 ms</td>
</tr>
</tbody>
</table>
</div>Anatomy
- table.thin-table with a caption
- Header cells with scope
- Optional div.thin-table-wrap as a focusable, labelled scroll region
Variants and sizes
- Simple table — shown above
- Scrolling wrapper — shown above
- Custom minimum size — shown above
States and difficult content
Rendered fixtures exercise authored content and constrained layouts with the same production assets.
Narrow, localized, and right-to-left
Headers wrap and the region scrolls in the reading direction.
<div dir="rtl" lang="ar" style="max-inline-size: 20rem">
<div class="thin-table-wrap" tabindex="0" role="region" aria-labelledby="rtl-caption">
<table class="thin-table">
<caption id="rtl-caption">الطلبات</caption>
<thead>
<tr>
<th scope="col">الطلب</th>
<th scope="col">المجموع الإجمالي بعد الخصم</th>
</tr>
</thead>
<tbody>
<tr>
<td>1024</td>
<td>64</td>
</tr>
</tbody>
</table>
</div>
</div>Show code
<div dir="rtl" lang="ar" style="max-inline-size: 20rem">
<div class="thin-table-wrap" tabindex="0" role="region" aria-labelledby="rtl-caption">
<table class="thin-table">
<caption id="rtl-caption">الطلبات</caption>
<thead>
<tr>
<th scope="col">الطلب</th>
<th scope="col">المجموع الإجمالي بعد الخصم</th>
</tr>
</thead>
<tbody>
<tr>
<td>1024</td>
<td>64</td>
</tr>
</tbody>
</table>
</div>
</div>- Many columns at narrow width — shown above
- Long localized headers — shown above
- Right-to-left reading direction — shown above
- Forced colors — shown above
Interaction and keyboard behavior
The wrapper is focusable so keyboard users can scroll it; the table itself is not interactive.
Accessibility
Keep the caption and header scopes. Name the scroll region after the caption and make it focusable only when it scrolls.
- Contract
NATIVE- Basis
- Native <table> with caption and header scope; no APG widget
API
Use table.thin-table. Wrap a wide table in div.thin-table-wrap with tabindex=0, role=region, and aria-labelledby pointing at the caption. Set --thin-table-min-size to the width below which the wrapper scrolls.
Behavior tier: native
Custom properties
--thin-table-min-size36remMinimum inline size before the wrapper scrolls.Fallback
Without CSS the native table keeps its structure and the page scrolls horizontally if it must.
Assets and dependencies
/components.css
Dependencies: None
Source: packages/ui/src/items/table/style.ts
Composition
Derived from the examples and style specs, not authored.