# Table

A table arranges many items of the same kind in rows and columns, to compare and act. On mobile, each row becomes a card.

## Playground

```html
<div style="inline-size: 100%"><div class="feitio-table-scroll" tabindex="0" role="region" aria-label="Name"><table class="feitio-table"><thead><tr><th scope="col">Name</th><th scope="col">When</th><th scope="col">Status</th><th scope="col" data-align="end">Runs</th><th scope="col"><span class="feitio-visually-hidden">Actions</span></th></tr></thead><tbody><tr><td class="title">Weekly backup</td><td data-label="When">Sunday, 3 am</td><td data-label="Status"><span class="feitio-tag" data-status="ok"><svg class="feitio-icon" aria-hidden="true"><use href="/feitio/icons/sprite.svg#feitio-check"></use></svg>On time</span></td><td data-align="end" data-label="Runs">48</td><td class="actions"><a class="feitio-button" href="#playground" data-size="small">Edit<span class="feitio-visually-hidden"> Weekly backup</span></a></td></tr><tr><td class="title">Water the plants</td><td data-label="When">Tuesday, 9 am</td><td data-label="Status"><span class="feitio-tag" data-status="warn"><svg class="feitio-icon" aria-hidden="true"><use href="/feitio/icons/sprite.svg#feitio-warn"></use></svg>Late</span></td><td data-align="end" data-label="Runs">3</td><td class="actions"><a class="feitio-button" href="#playground" data-size="small">Edit<span class="feitio-visually-hidden"> Water the plants</span></a></td></tr></tbody></table></div></div>
```

## When to use

-   For items compared by the same characteristics: schedules with when and who, services with status.
-   On work screens, almost always with `data-density="compact"`.

## When not to use

-   **One item, several characteristics:** SummaryList.
-   **Things to do, each with a status:** TaskList.
-   **To lay out the page:** a table is data, never positioning.

## Examples

### A work table

Caption, header with the ink line, numbers on the right and each row’s action at the end.

Show code

```html
<div class="feitio-table-scroll" tabindex="0" role="region" aria-labelledby="agendamentos">
  <table class="feitio-table">
    <caption id="agendamentos">Agendamentos</caption>
    <thead><tr><th scope="col">Nome</th>…<th scope="col" data-align="end">Disparos</th></tr></thead>
    <tbody><tr><td class="title">Backup semanal</td>…<td data-align="end" data-label="Disparos">48</td></tr></tbody>
  </table>
</div>
```

### On mobile

In a box narrower than 40rem, each row becomes a card: the name on top, each value with its column name beside it (`data-label`), the actions below.

Show code

```html
<td class="title">Backup semanal</td>
<td data-label="Quando">Domingo, 3h</td>
```

### Sort by header

The sorting column is a link: the server returns the sorted page. The sorted column gets `aria-sort` and the arrow.

Show code

```html
<th scope="col" aria-sort="ascending"><a href="?ordem=prazo">Prazo…</a></th>
```

### Batch action

A box per row and the batch actions on top, in small buttons. It is a form: the ticked boxes go along with the button pressed.

Show code

```html
<form action="/tarefas/lote" method="post">
  <button type="submit" name="acao" value="concluir" class="feitio-button" data-size="small">Concluir selecionadas</button>
  …
  <td class="select"><input type="checkbox" name="ids" value="12" aria-label="Selecionar revisar o contrato"></td>
</form>
```

With no rows, the table becomes an [EmptyState](/en/components/emptystate/), in place of the rows. Never a header alone with nothing below.

## Anatomy

1.  **Caption:** the table’s name, read by screen readers.
2.  **Header:** soft text, with the ink line below.
3.  **Row:** separated from the next by a hairline.
4.  **Numbers** on the right, with same-width figures.
5.  **Row action:** a small button, at the end.

## States

-   **Hover on a row:** a slightly darker tone, very light, so the eye keeps the row. It is not selection.
-   **Density:** comfortable for reading, compact on work screens; the switch animates.
-   **Narrow box:** each row becomes a card. **Medium box and wide table:** it scrolls inside its own box; the page never scrolls sideways.

## Do and don’t

Do

Item

Value

Photos

1.204

Videos

38

Numbers on the right: the digits line up and comparison is by eye.

Don’t

Item

Value

Photos

1.204

Videos

38

Everything centered: the numbers do not line up.

Do

Backup

Edit

The action with a word, small, at the end of the row.

Don’t

Backup

Plants

Alternating stripes and icon-only actions: noise, and nobody knows what the icon does.

## Writing

-   Header: one or two words, without repeating the unit in each cell.
-   Empty cell: a dash, with hidden text ("no due date") for screen readers.

## Accessibility

-   `<caption>` with the name and `<th scope="col">` on each header.
-   Each row’s action says which row it belongs to ("Edit weekly backup"), with hidden text.
-   The scrolling box is a named region and takes focus.

## Attributes

Attribute

Values

What for

`class="feitio-table"`

required

Hairlines, header with the ink line, same-width figures.

`class="feitio-table-scroll" tabindex="0"`

around

Measures its own width: narrow, it turns into cards; medium, it scrolls. With `tabindex="0"`, `role="region"` and a name.

`class="title"`

on the name cell

The card title on mobile.

`data-label`

on the other cells

The column name, next to the value on the card.

`data-align="end"`

on the number column

Numbers on the right.

`class="actions"`

on the actions cell

Small buttons, at the end.

`aria-sort`

`"ascending"`, `"descending"`

On the sorted column.
