Skip to content
Alpha

Hololink UI is under active development. Components, APIs and these docs may change without notice.

Holo Table

<holo-table> wraps a native <table>. Write the table as you normally would, with <caption>, <thead>, <tbody>, <th scope="col"> and <td>, and put it inside <holo-table>. The table stays in the light DOM, so its semantics are untouched. Set responsive to wrap the table in a horizontally-scrollable container (overflow-x: auto) instead of breaking table semantics with layout hacks.

Always include the <table> element. The HTML parser drops <thead>, <tr>, <th> and <td> tags that are not inside a <table>, so they never reach the component.

The cell, header and caption styles live in the global stylesheet, because Shadow DOM styles cannot reach light-DOM cells. Load @philbob-sideprojects/hololink-ui/styles/global.css as described in Installation.

Use it for:

  • Comparing values across rows and columns: records, prices, schedules.
  • Data where each cell needs a row header and a column header to make sense.

Don’t use it for:

  • Page layout. Use Grid or Stack.
  • A simple series of items. Use List.
  • Card-like record summaries. Use Card.
Team roster
NameRoleLocation
Ada LovelaceMathematicianLondon
Grace HopperComputer ScientistNew York
<holo-table>
<table>
<caption>
Team roster
</caption>
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Role</th>
<th scope="col">Location</th>
</tr>
</thead>
<tbody>
<tr>
<td>Ada Lovelace</td>
<td>Mathematician</td>
<td>London</td>
</tr>
</tbody>
</table>
</holo-table>

Wraps the table in a horizontally-scrollable container on narrow viewports.

<holo-table responsive>
<table>
<caption>
Team roster
</caption>
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Role</th>
</tr>
</thead>
<tbody>
<tr>
<td>Ada Lovelace</td>
<td>Mathematician</td>
</tr>
</tbody>
</table>
</holo-table>

Override the --holo-table-* hooks on <holo-table> or any ancestor:

holo-table {
--holo-table-cell-padding: var(--s-space-xs) var(--s-space-sm);
--holo-table-border-color: var(--s-color-border-strong);
}

Your <table> stays in the light DOM, inside <holo-table>, so it keeps its native table roles, <caption> and any scope you set. The component adds no key handling of its own. If you append <thead>/<tbody> directly with DOM APIs instead, the component wraps them in a <table> in its shadow root, with a <caption> from the caption prop.

With responsive, the table is wrapped in a container with overflow-x: auto, so wide tables scroll horizontally without changing their semantics. The container has tabindex="0", so keyboard users can focus it and scroll with the arrow keys, and shows a focus ring. When the table has a caption (your <caption>, or the caption prop), the container is also a role="region" named by it.

Key Action
Tab Moves focus to the scroll container (responsive only)
ArrowLeft, ArrowRight Scrolls the focused container horizontally

You provide:

  • A <caption> (or the caption prop when appending sections with DOM APIs), so the table, and with responsive the scroll region, has an accessible name.
  • <th scope="col"> for column headers and <th scope="row"> for row headers. Do not use <td> as a header.
  • Any sort, filter or row-action controls, with accessible names and sort state (aria-sort) on the relevant <th>.

Importing

import '@philbob-sideprojects/hololink-ui/holo-table';

Properties

PropertyAttributeTypeDefaultDescription
captioncaptionstring—Accessible caption/title for the table, rendered as a native <caption>. Only applies when sections are appended directly to holo-table; with a slotted <table>, author a <caption> inside it instead.
responsiveresponsivebooleanfalseIf true, wraps the table in a horizontally-scrollable container (overflow-x: auto) for narrow viewports instead of breaking table semantics with layout hacks. The container is focusable so keyboard users can scroll it, and is a region named by the table's caption when it has one.

Slots

SlotDescription
(default)A native <table> (recommended), or <thead>, <tbody> and <tfoot> sections created with DOM APIs.

CSS custom properties

PropertyDescription
--holo-table-border-colorColor of the cell dividers.
--holo-table-caption-colorText color of the caption.
--holo-table-cell-paddingPadding of header and data cells. Tighter by default when the table is narrower than 32rem.
--holo-table-colorText color of the table.
--holo-table-header-colorText color of header cells.