Tables
tier 2 — classes
One class on the <table>. Write the thead and tbody
in the page.
Basic
Headers are uppercased and muted by the class. .col-muted is for secondary
columns — timestamps, counts — and stops them from wrapping.
| Order | Short description | Priority | Age |
|---|---|---|---|
| ORD-4209 | Outlook will not start after update | P3 | 4 min |
| ORD-4204 | VPN disconnects every few minutes | P1 | 22 min |
| ORD-4198 | Request: second monitor | P4 | 1 h |
<table class="table">
<thead>
<tr><th>Order</th><th>Short description</th><th>Priority</th><th>Age</th></tr>
</thead>
<tbody>
<tr><td>ORD-4209</td><td>Outlook will not start after update</td><td><span class="badge badge-warn">P3</span></td><td class="col-muted">4 min</td></tr>
<tr><td>ORD-4204</td><td>VPN disconnects every few minutes</td><td><span class="badge badge-danger">P1</span></td><td class="col-muted">22 min</td></tr>
<tr><td>ORD-4198</td><td>Request: second monitor</td><td><span class="badge">P4</span></td><td class="col-muted">1 h</td></tr>
</tbody>
</table>
Clickable rows
.tr-clickable adds the pointer and the hover fill. Keep a real focusable
control in the row for keyboard users — a whole row cannot be tabbed to.
| Order | Pending | Owner | |
|---|---|---|---|
| Mailbox quota exceeded | 2 | unclaimed | |
| Printer offline in HQ-3 | 0 | J. Weber |
<table class="table">
<thead>
<tr><th>Order</th><th>Pending</th><th>Owner</th><th></th></tr>
</thead>
<tbody>
<tr class="tr-clickable">
<td>Mailbox quota exceeded</td>
<td><span class="badge badge-warn">2</span></td>
<td class="col-muted">unclaimed</td>
<td><button class="btn btn-sm btn-icon" aria-label="Open order"><i class="ri-arrow-right-line"></i></button></td>
</tr>
<tr class="tr-clickable">
<td>Printer offline in HQ-3</td>
<td><span class="badge">0</span></td>
<td class="col-muted">J. Weber</td>
<td><button class="btn btn-sm btn-icon" aria-label="Open order"><i class="ri-arrow-right-line"></i></button></td>
</tr>
</tbody>
</table>
With a toolbar, in a card
The standard list page: filter bar above, table inside a card.
| Order | State | Age |
|---|---|---|
| ORD-4209 | Pending | 4 min |
| ORD-4204 | Approved | 22 min |
| ORD-4198 | Rejected | 1 h |
<div class="toolbar">
<div class="toolbar-filters">
<input class="form-input toolbar-input" type="search" placeholder="Search…" />
<label class="form-check"><input type="checkbox" checked /> Only mine</label>
</div>
<span class="toolbar-count">3 of 128</span>
</div>
<div class="card">
<table class="table">
<thead>
<tr><th>Order</th><th>State</th><th>Age</th></tr>
</thead>
<tbody>
<tr><td>ORD-4209</td><td><span class="badge badge-warn">Pending</span></td><td class="col-muted">4 min</td></tr>
<tr><td>ORD-4204</td><td><span class="badge badge-go">Approved</span></td><td class="col-muted">22 min</td></tr>
<tr><td>ORD-4198</td><td><span class="badge badge-danger">Rejected</span></td><td class="col-muted">1 h</td></tr>
</tbody>
</table>
</div>
.sedna-scroll-x container, so the
page body never scrolls sideways.
Extensions
Sortable, numeric and selected
Put a <button class="th-sort"> inside the header cell filling it, and set
aria-sort — the arrow is keyed off the attribute a screen reader announces, so
the two cannot disagree. .col-num goes on the th and the
td; row selection is aria-selected on the
<tr>. The header buttons here do nothing — which column
is sorted is your query, and the arrow follows aria-sort.
| ORD-4204 | 22 min | 3 |
| ORD-4209 | 4 min | 0 |
| ORD-4187 | 1 h 12 min | 12 |
| 3 orders | 15 |
<table class="table">
<thead>
<tr>
<th aria-sort="none"><button class="th-sort" type="button">Order</button></th>
<th aria-sort="descending"><button class="th-sort" type="button">Age</button></th>
<th class="col-num" aria-sort="none"><button class="th-sort" type="button">Reopens</button></th>
</tr>
</thead>
<tbody>
<tr aria-selected="true"><td>ORD-4204</td><td class="col-muted">22 min</td><td class="col-num">3</td></tr>
<tr><td>ORD-4209</td><td class="col-muted">4 min</td><td class="col-num">0</td></tr>
<tr><td>ORD-4187</td><td class="col-muted">1 h 12 min</td><td class="col-num">12</td></tr>
</tbody>
<tfoot>
<tr><td>3 orders</td><td></td><td class="col-num">15</td></tr>
</tfoot>
</table>
Sorting from C#
Live — sort it. SednaSort holds which column and which
direction, and AriaSort(column) renders the attribute on every sortable header —
none on the others, which is what shows the hover arrow.
Toggle(column) starts a new column ascending and turns the sorted one;
thenNone: true returns a descending column to unsorted. The ordering is still
your query, and ToQuery() / FromQuery() carry the sort in an
address as age or -age.
| ORD-4187 | 72 min | 12 |
| ORD-4204 | 22 min | 3 |
| ORD-4209 | 4 min | 0 |
<table class="table">
<thead>
<tr>
<th aria-sort="@_sort.AriaSort("order")">
<button class="th-sort" type="button" @onclick="@(() => Sort("order"))">Order</button>
</th>
<th aria-sort="@_sort.AriaSort("age")">
<button class="th-sort" type="button" @onclick="@(() => Sort("age"))">Age</button>
</th>
<th class="col-num" aria-sort="@_sort.AriaSort("reopens")">
<button class="th-sort" type="button" @onclick="@(() => Sort("reopens"))">Reopens</button>
</th>
</tr>
</thead>
<tbody>
@foreach (var row in Rows())
{
<tr><td>@row.Order</td><td class="col-muted">@row.Age min</td><td class="col-num">@row.Reopens</td></tr>
}
</tbody>
</table>
@code {
private sealed record Row(string Order, int Age, int Reopens);
private static readonly Row[] All =
[
new("ORD-4204", 22, 3),
new("ORD-4209", 4, 0),
new("ORD-4187", 72, 12),
];
// The sort is the app's state. SednaSort only answers aria-sort for each header,
// which is what the arrow follows and what a screen reader announces.
private SednaSort _sort = SednaSort.By("age", descending: true);
private void Sort(string column) => _sort = _sort.Toggle(column);
// The ordering itself stays the app's query — here a LINQ sort, in an app a database one.
private IEnumerable<Row> Rows()
{
IEnumerable<Row> rows = _sort.Column switch
{
"order" => All.OrderBy(r => r.Order, StringComparer.Ordinal),
"age" => All.OrderBy(r => r.Age),
"reopens" => All.OrderBy(r => r.Reopens),
_ => All,
};
return _sort.Descending ? rows.Reverse() : rows;
}
}
Sticky header
.table--sticky needs a scroll container around the table with a
max-height, and silently does nothing without one: the header sticks to the
nearest scrolling ancestor, and with none that is the page, where the topbar already is.
| Order | Assignment group | Age (min) |
|---|---|---|
| ORD-4209 | EU-Central | 4 |
| ORD-4204 | EU-West | 22 |
| ORD-4198 | EU-Central | 37 |
| ORD-4187 | SD-Applications | 72 |
| ORD-4166 | EU-West | 118 |
| ORD-4140 | EU-Central | 203 |
<div class="sedna-scroll" style="max-height:180px; overflow-y:auto" tabindex="0" role="group" aria-label="Order queue">
<table class="table table--sticky table--zebra">
<thead><tr><th>Order</th><th>Assignment group</th><th class="col-num">Age (min)</th></tr></thead>
<tbody>
<tr><td>ORD-4209</td><td>EU-Central</td><td class="col-num">4</td></tr>
<tr><td>ORD-4204</td><td>EU-West</td><td class="col-num">22</td></tr>
<tr><td>ORD-4198</td><td>EU-Central</td><td class="col-num">37</td></tr>
<tr><td>ORD-4187</td><td>SD-Applications</td><td class="col-num">72</td></tr>
<tr><td>ORD-4166</td><td>EU-West</td><td class="col-num">118</td></tr>
<tr><td>ORD-4140</td><td>EU-Central</td><td class="col-num">203</td></tr>
</tbody>
</table>
</div>
Pinned column
.table--pin-start holds the first column still while the rest of a wide table
scrolls under it — use it for the column a row is identified by;
.table--pin-end does the same at the other edge, where a row's actions are.
Both need a horizontal scroll container, .sedna-scroll-x, and neither combines
with .table--stack, which has no sideways scroll to pin against.
Scroll this table both ways.
| Staff ID | Surname | First name | Company | Location | Department | Cost centre | Manager | Card | |
|---|---|---|---|---|---|---|---|---|---|
| 10020266 | Aebischer | Nadine | nadine.aebischer@example.com | Northwind Retail | Zürich | Field Service | 4210 | M. Brunner | 8841 |
| 10020412 | Baumgartner | Tobias | tobias.baumgartner@example.com | Northwind Retail | Bern | Application Management | 4180 | S. Kaufmann | 8912 |
| 10021077 | Cavalli | Elena | elena.cavalli@example.com | Northwind Italy | Milano | Field Service | 4210 | M. Brunner | 9034 |
| 10021340 | Dörig | Simon | simon.doerig@example.com | Northwind Retail | St. Gallen | Infrastructure | 4090 | P. Weber | 9101 |
| 10021688 | Eichenberger | Judith | judith.eichenberger@example.com | Northwind Retail | Zürich | Service Desk | 4155 | S. Kaufmann | 9188 |
| 10022019 | Frei | Marc | marc.frei@example.com | Northwind Germany | Stuttgart | Infrastructure | 4090 | P. Weber | 9240 |
<div class="sedna-scroll sedna-scroll-x" style="--scroll-max: 220px" tabindex="0" role="group" aria-label="Employee register">
<table class="table table--sticky table--zebra table--pin-start">
<thead>
<tr>
<th>Staff ID</th>
<th>Surname</th>
<th>First name</th>
<th>E-mail</th>
<th>Company</th>
<th>Location</th>
<th>Department</th>
<th>Cost centre</th>
<th>Manager</th>
<th class="col-num">Card</th>
</tr>
</thead>
<tbody>
<tr><td>10020266</td><td>Aebischer</td><td>Nadine</td><td>nadine.aebischer@example.com</td><td>Northwind Retail</td><td>Zürich</td><td>Field Service</td><td>4210</td><td>M. Brunner</td><td class="col-num">8841</td></tr>
<tr aria-selected="true"><td>10020412</td><td>Baumgartner</td><td>Tobias</td><td>tobias.baumgartner@example.com</td><td>Northwind Retail</td><td>Bern</td><td>Application Management</td><td>4180</td><td>S. Kaufmann</td><td class="col-num">8912</td></tr>
<tr><td>10021077</td><td>Cavalli</td><td>Elena</td><td>elena.cavalli@example.com</td><td>Northwind Italy</td><td>Milano</td><td>Field Service</td><td>4210</td><td>M. Brunner</td><td class="col-num">9034</td></tr>
<tr><td>10021340</td><td>Dörig</td><td>Simon</td><td>simon.doerig@example.com</td><td>Northwind Retail</td><td>St. Gallen</td><td>Infrastructure</td><td>4090</td><td>P. Weber</td><td class="col-num">9101</td></tr>
<tr><td>10021688</td><td>Eichenberger</td><td>Judith</td><td>judith.eichenberger@example.com</td><td>Northwind Retail</td><td>Zürich</td><td>Service Desk</td><td>4155</td><td>S. Kaufmann</td><td class="col-num">9188</td></tr>
<tr><td>10022019</td><td>Frei</td><td>Marc</td><td>marc.frei@example.com</td><td>Northwind Germany</td><td>Stuttgart</td><td>Infrastructure</td><td>4090</td><td>P. Weber</td><td class="col-num">9240</td></tr>
</tbody>
</table>
</div>
Pinned actions
.table--pin-end on its own, for the commonest reason to pin the far edge: the
row's actions stay reachable however wide the table is. .col-fit on the
header and the cell keeps the column to its buttons, and the edge shadow appears only
while there is a column scrolled under it. Narrow this window to see it.
| Reservation | Order | Customer | From | To | Reason | Confidence | Actions |
|---|---|---|---|---|---|---|---|
| rsv-20419 | ORD-4209 | Priya Nair | EU-Central | EU-West | Carrier capacity in Hamburg is exhausted until Thursday | 0.87 | |
| rsv-20420 | ORD-4213 | Tomás Ferreira | EU-West | EU-Central | Customer address changed after the pick list was printed | 0.64 | |
| rsv-20424 | ORD-4250 | Alex Fischer | EU-Central | EU-Central | Split shipment: two lines are back-ordered until the next inbound | 0.91 |
<div class="sedna-scroll-x" tabindex="0" role="group" aria-label="Pending reservations">
<table class="table table--pin-end">
<thead>
<tr>
<th>Reservation</th>
<th>Order</th>
<th>Customer</th>
<th>From</th>
<th>To</th>
<th>Reason</th>
<th class="col-num">Confidence</th>
<th class="col-fit"><span class="visually-hidden">Actions</span></th>
</tr>
</thead>
<tbody>
<tr>
<td>rsv-20419</td><td>ORD-4209</td><td>Priya Nair</td><td>EU-Central</td><td>EU-West</td>
<td>Carrier capacity in Hamburg is exhausted until Thursday</td><td class="col-num">0.87</td>
<td class="col-fit">
<div class="sedna-row sedna-gap-0">
<button class="btn btn-sm btn-ghost btn-icon" type="button" aria-label="Approve rsv-20419"><i class="ri-check-line"></i></button>
<button class="btn btn-sm btn-ghost btn-icon" type="button" aria-label="Decline rsv-20419"><i class="ri-close-line"></i></button>
</div>
</td>
</tr>
<tr>
<td>rsv-20420</td><td>ORD-4213</td><td>Tomás Ferreira</td><td>EU-West</td><td>EU-Central</td>
<td>Customer address changed after the pick list was printed</td><td class="col-num">0.64</td>
<td class="col-fit">
<div class="sedna-row sedna-gap-0">
<button class="btn btn-sm btn-ghost btn-icon" type="button" aria-label="Approve rsv-20420"><i class="ri-check-line"></i></button>
<button class="btn btn-sm btn-ghost btn-icon" type="button" aria-label="Decline rsv-20420"><i class="ri-close-line"></i></button>
</div>
</td>
</tr>
<tr>
<td>rsv-20424</td><td>ORD-4250</td><td>Alex Fischer</td><td>EU-Central</td><td>EU-Central</td>
<td>Split shipment: two lines are back-ordered until the next inbound</td><td class="col-num">0.91</td>
<td class="col-fit">
<div class="sedna-row sedna-gap-0">
<button class="btn btn-sm btn-ghost btn-icon" type="button" aria-label="Approve rsv-20424"><i class="ri-check-line"></i></button>
<button class="btn btn-sm btn-ghost btn-icon" type="button" aria-label="Decline rsv-20424"><i class="ri-close-line"></i></button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
Column widths
.col-control gives a cell holding an input, a select or a
.value-trigger a floor and makes the control fill it;
.col-prose lets a sentence or a distinguished name give way instead of taking
the table; .col-fit takes the width of its content and no more. Put each on the
th and the td, and set --col-control-min,
--col-control-max, --col-prose-min or
--col-prose-max on the cell where a column needs a different number.
| AD attribute | HR field | Last result | Actions | |
|---|---|---|---|---|
| Mapped | Written for 1 204 of 1 211 accounts. | |||
| Failed | Declined by CN=svc-hr-sync,OU=Service Accounts,OU=Managed,DC=example,DC=com — insufficient access rights on the target container. |
<div class="sedna-scroll-x">
<table class="table">
<thead>
<tr>
<th class="col-fit"></th>
<th class="col-control">AD attribute</th>
<th class="col-control">HR field</th>
<th class="col-prose">Last result</th>
<th class="col-fit">Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td class="col-fit"><i class="ri-checkbox-circle-line"></i><span class="visually-hidden">Mapped</span></td>
<td class="col-control">
<select class="form-select" aria-label="AD attribute for Location">
<option>physicalDeliveryOfficeName</option>
<option>givenName</option>
<option>department</option>
</select>
</td>
<td class="col-control">
<select class="form-select" aria-label="HR field for physicalDeliveryOfficeName">
<option>Location</option>
<option>FirstName</option>
<option>Department</option>
</select>
</td>
<td class="col-prose">Written for 1 204 of 1 211 accounts.</td>
<td class="col-fit"><button class="btn btn-sm" type="button">Edit</button></td>
</tr>
<tr>
<td class="col-fit"><i class="ri-error-warning-line"></i><span class="visually-hidden">Failed</span></td>
<td class="col-control">
<select class="form-select" aria-label="AD attribute for CostCentre">
<option>extensionAttribute7</option>
<option>employeeNumber</option>
</select>
</td>
<td class="col-control">
<select class="form-select" aria-label="HR field for extensionAttribute7">
<option>CostCentre</option>
<option>StaffId</option>
</select>
</td>
<td class="col-prose">
Declined by CN=svc-hr-sync,OU=Service Accounts,OU=Managed,DC=example,DC=com —
insufficient access rights on the target container.
</td>
<td class="col-fit"><button class="btn btn-sm" type="button">Edit</button></td>
</tr>
</tbody>
</table>
</div>
Expandable rows
The detail row is a real <tr class="tr-detail"> immediately after its
parent, and its cell spans every column. Shown expanded — which row is open
is your app's state, with aria-expanded on the control that toggles it.
| Order | Reservation |
|---|---|
| ORD-4209 | Reroute to EU-West |
Confidence0.87
Matched on"VPN" + "disconnect" | |
| ORD-4204 | Ask for the client version |
<table class="table">
<thead><tr><th>Order</th><th>Reservation</th></tr></thead>
<tbody>
<tr class="tr-clickable">
<td>ORD-4209</td><td>Reroute to EU-West</td>
</tr>
<tr class="tr-detail">
<td colspan="2">
<div class="tr-detail-body">
<div class="kv"><span class="k">Confidence</span><span class="v">0.87</span></div>
<div class="kv"><span class="k">Matched on</span><span class="v">"VPN" + "disconnect"</span></div>
</div>
</td>
</tr>
<tr class="tr-clickable">
<td>ORD-4204</td><td>Ask for the client version</td>
</tr>
</tbody>
</table>
Grouped rows
A .tr-group row heads the rows after it — a state, a day, a customer.
Its one cell is a <th scope="rowgroup"> spanning the table, so a screen
reader announces the group with every row under it, and the .tr-group-body
inside it is a flex row that takes whatever belongs to the group: a sentence, a
badge for the count, a chip for the filter that
made it, with .tr-group-count at the far end. Under
.table--sticky the group row pins beneath the header.
| Order | Customer | Reservation | Value |
|---|---|---|---|
Waiting on you
3
EU-Central
3 of 128 | |||
| ORD-4209 | Priya Nair | Reroute to EU-West | 1,240.00 |
| ORD-4211 | Tomás Ferreira | Hold for address check | 318.40 |
| ORD-4250 | Alex Fischer | Split shipment | 2,080.00 |
Decided today
2
2 of 128 | |||
| ORD-4204 | Nadine Aebischer | Ask for the client version | 96.00 |
| ORD-4198 | Simon Dörig | Approve as offered | 440.00 |
<table class="table">
<thead>
<tr><th>Order</th><th>Customer</th><th>Reservation</th><th class="col-num">Value</th></tr>
</thead>
<tbody>
<tr class="tr-group">
<th colspan="4" scope="rowgroup">
<div class="tr-group-body">
Waiting on you
<span class="badge badge-warn">3</span>
<span class="chip">EU-Central <button class="chip-dismiss" type="button" aria-label="Remove the EU-Central filter"><i class="ri-close-line"></i></button></span>
<span class="tr-group-count">3 of 128</span>
</div>
</th>
</tr>
<tr><td>ORD-4209</td><td>Priya Nair</td><td>Reroute to EU-West</td><td class="col-num">1,240.00</td></tr>
<tr><td>ORD-4211</td><td>Tomás Ferreira</td><td>Hold for address check</td><td class="col-num">318.40</td></tr>
<tr><td>ORD-4250</td><td>Alex Fischer</td><td>Split shipment</td><td class="col-num">2,080.00</td></tr>
<tr class="tr-group">
<th colspan="4" scope="rowgroup">
<div class="tr-group-body">
Decided today
<span class="badge badge-go">2</span>
<span class="tr-group-count">2 of 128</span>
</div>
</th>
</tr>
<tr><td>ORD-4204</td><td>Nadine Aebischer</td><td>Ask for the client version</td><td class="col-num">96.00</td></tr>
<tr><td>ORD-4198</td><td>Simon Dörig</td><td>Approve as offered</td><td class="col-num">440.00</td></tr>
</tbody>
</table>
A filter per column
.tr-filter is a second header row holding a .form-input-sm or a
.form-select per column, for an admin table filtered column by column — the
toolbar above a table is still the default. Give every control an
aria-label: the heading above it is not its label. Under
.table--sticky it pins beneath the header, and a .tr-group row
pins beneath both; set --table-filter-height on the table if your controls are
not the small size.
| Order | Status | Owner |
|---|---|---|
| ORD-4209 | Open | Alex Fischer |
| ORD-4204 | Held | Priya Nair |
| ORD-4187 | Open | Jordan Weiss |
| ORD-4182 | Open | Alex Fischer |
| ORD-4176 | Held | Priya Nair |
| ORD-4171 | Open | Jordan Weiss |
| ORD-4166 | Open | Alex Fischer |
<div class="sedna-scroll" style="max-height:260px">
<table class="table table--sticky">
<thead>
<tr><th>Order</th><th>Status</th><th>Owner</th></tr>
<tr class="tr-filter">
<th><input class="form-input form-input-sm" type="search" placeholder="ORD-…" aria-label="Filter by order" /></th>
<th>
<select class="form-input form-select form-input-sm" aria-label="Filter by status">
<option>Any</option><option>Open</option><option>Held</option>
</select>
</th>
<th><input class="form-input form-input-sm" type="search" aria-label="Filter by owner" /></th>
</tr>
</thead>
<tbody>
<tr><td>ORD-4209</td><td>Open</td><td>Alex Fischer</td></tr>
<tr><td>ORD-4204</td><td>Held</td><td>Priya Nair</td></tr>
<tr><td>ORD-4187</td><td>Open</td><td>Jordan Weiss</td></tr>
<tr><td>ORD-4182</td><td>Open</td><td>Alex Fischer</td></tr>
<tr><td>ORD-4176</td><td>Held</td><td>Priya Nair</td></tr>
<tr><td>ORD-4171</td><td>Open</td><td>Jordan Weiss</td></tr>
<tr><td>ORD-4166</td><td>Open</td><td>Alex Fischer</td></tr>
</tbody>
</table>
</div>
A filter for each type of column
Each filter is a control that already exists, at the small size, so the row stays one
height. Text is an .input-group--sm with a search affix and an
.input-clear, which shows only while the field has a value. One choice is a
.form-select-sm, holding badges through
<selectedcontent> where the values are states. Several choices, and a
date range, are a .form-trigger: a button shaped like the field beside it that
reads 2 selected and opens a popover of checkboxes or a
date picker. A number range is two fields in one group, and yes /
no is a .segmented--sm with Any. .col-filtered on the
heading and the filter cell marks the columns that are set. Open the region and the
date.
| Host, filtered | Environment | Region, filtered | Status | CPU | Last deploy, filtered | Monitored |
|---|---|---|---|---|---|---|
|
Region
|
–
|
September 2026
|
||||
| orders-console-01 | Production | EU-West | Running | 42% | 11 Sep 2026, 16:40 | Yes |
| orders-console-02 | Production | EU-Central | Degraded | 91% | 10 Sep 2026, 09:15 | Yes |
| orders-api-04 | Staging | EU-West | Running | 17% | 9 Sep 2026, 14:02 | No |
| orders-worker-07 | Production | EU-Central | Stopped | 0% | 7 Sep 2026, 11:30 | Yes |
<div class="sedna-scroll-x">
<table class="table">
<thead>
<tr>
<th class="col-filtered">Host<span class="visually-hidden">, filtered</span></th>
<th>Environment</th>
<th class="col-filtered">Region<span class="visually-hidden">, filtered</span></th>
<th>Status</th>
<th class="col-num">CPU</th>
<th class="col-filtered">Last deploy<span class="visually-hidden">, filtered</span></th>
<th>Monitored</th>
</tr>
<tr class="tr-filter">
<th class="col-control col-filtered" style="--col-control-min: 11rem">
<div class="input-group input-group--sm">
<span class="input-affix"><i class="ri-search-line"></i></span>
<input class="form-input" type="search" value="orders" placeholder="Host name" aria-label="Filter by host" />
<button class="input-clear" type="button" aria-label="Clear the host filter"><i class="ri-close-line"></i></button>
</div>
</th>
<th class="col-control" style="--col-control-min: 8rem">
<select class="form-select form-select-sm" aria-label="Filter by environment">
<option>Any</option>
<option>Production</option>
<option>Staging</option>
</select>
</th>
<th class="col-control col-filtered" style="--col-control-min: 9rem">
<button class="form-input form-input-sm form-trigger" type="button" popovertarget="ft-region" aria-label="Filter by region, 2 selected">
<span>2 selected</span>
</button>
<div class="popover" id="ft-region" popover>
<strong class="popover-title">Region</strong>
<div class="sedna-col">
<label class="form-check"><input type="checkbox" checked /> EU-West</label>
<label class="form-check"><input type="checkbox" checked /> EU-Central</label>
<label class="form-check"><input type="checkbox" /> US-East</label>
<label class="form-check"><input type="checkbox" /> AP-South</label>
</div>
<div class="form-actions form-actions--split">
<button class="btn btn-sm btn-ghost" type="button">Clear</button>
<button class="btn btn-sm btn-primary" type="button" popovertarget="ft-region" popovertargetaction="hide">Apply</button>
</div>
</div>
</th>
<th class="col-control" style="--col-control-min: 9rem">
<select class="form-select form-select-sm" aria-label="Filter by status">
<button>
<selectedcontent></selectedcontent>
</button>
<option value="" selected>Any</option>
<option value="running"><span class="badge badge-go">Running</span></option>
<option value="degraded"><span class="badge badge-warn">Degraded</span></option>
<option value="stopped"><span class="badge badge-danger">Stopped</span></option>
</select>
</th>
<th class="col-control col-num" style="--col-control-min: 8rem">
<div class="input-group input-group--sm">
<input class="form-input" type="number" placeholder="Min" aria-label="Lowest CPU, in percent" />
<span class="input-affix">–</span>
<input class="form-input" type="number" placeholder="Max" aria-label="Highest CPU, in percent" />
</div>
</th>
<th class="col-control col-filtered" style="--col-control-min: 10rem">
<button class="form-input form-input-sm form-trigger" type="button" popovertarget="ft-deployed" aria-label="Filter by last deploy, 7 to 11 September 2026">
<i class="ri-calendar-line"></i><span>7–11 Sep 2026</span>
</button>
<div class="popover datepicker" id="ft-deployed" popover>
<div class="datepicker-head">
<button class="btn btn-ghost btn-icon btn-sm" type="button" aria-label="Previous month"><i class="ri-arrow-left-s-line"></i></button>
<span class="datepicker-title">September 2026</span>
<button class="btn btn-ghost btn-icon btn-sm" type="button" aria-label="Next month"><i class="ri-arrow-right-s-line"></i></button>
</div>
<div class="cal-month cal-month--mini">
<div class="cal-weekdays" aria-hidden="true">
<span class="cal-weekday">Mo</span>
<span class="cal-weekday">Tu</span>
<span class="cal-weekday">We</span>
<span class="cal-weekday">Th</span>
<span class="cal-weekday">Fr</span>
<span class="cal-weekday">Sa</span>
<span class="cal-weekday">Su</span>
</div>
<div class="cal-row">
<span class="cal-day cal-day--outside"></span>
<button class="cal-day" type="button" aria-label="Tuesday 1 September 2026" aria-pressed="false">1</button>
<button class="cal-day" type="button" aria-label="Wednesday 2 September 2026" aria-pressed="false">2</button>
<button class="cal-day" type="button" aria-label="Thursday 3 September 2026" aria-pressed="false">3</button>
<button class="cal-day" type="button" aria-label="Friday 4 September 2026" aria-pressed="false">4</button>
<button class="cal-day cal-day--weekend" type="button" aria-label="Saturday 5 September 2026" aria-pressed="false">5</button>
<button class="cal-day cal-day--weekend" type="button" aria-label="Sunday 6 September 2026" aria-pressed="false">6</button>
</div>
<div class="cal-row">
<button class="cal-day cal-day--range-start" type="button" aria-label="Monday 7 September 2026" aria-pressed="true">7</button>
<button class="cal-day cal-day--in-range" type="button" aria-label="Tuesday 8 September 2026" aria-pressed="true">8</button>
<button class="cal-day cal-day--in-range" type="button" aria-label="Wednesday 9 September 2026" aria-pressed="true">9</button>
<button class="cal-day cal-day--in-range" type="button" aria-label="Thursday 10 September 2026" aria-pressed="true">10</button>
<button class="cal-day cal-day--range-end" type="button" aria-label="Friday 11 September 2026" aria-pressed="true">11</button>
<button class="cal-day cal-day--weekend" type="button" aria-label="Saturday 12 September 2026" aria-pressed="false">12</button>
<button class="cal-day cal-day--weekend" type="button" aria-label="Sunday 13 September 2026" aria-pressed="false">13</button>
</div>
<div class="cal-row">
<button class="cal-day" type="button" aria-label="Monday 14 September 2026" aria-pressed="false">14</button>
<button class="cal-day" type="button" aria-label="Tuesday 15 September 2026" aria-pressed="false" aria-current="date">15</button>
<button class="cal-day" type="button" aria-label="Wednesday 16 September 2026" aria-pressed="false" disabled>16</button>
<button class="cal-day" type="button" aria-label="Thursday 17 September 2026" aria-pressed="false" disabled>17</button>
<button class="cal-day" type="button" aria-label="Friday 18 September 2026" aria-pressed="false" disabled>18</button>
<button class="cal-day cal-day--weekend" type="button" aria-label="Saturday 19 September 2026" aria-pressed="false" disabled>19</button>
<button class="cal-day cal-day--weekend" type="button" aria-label="Sunday 20 September 2026" aria-pressed="false" disabled>20</button>
</div>
<div class="cal-row">
<button class="cal-day" type="button" aria-label="Monday 21 September 2026" aria-pressed="false" disabled>21</button>
<button class="cal-day" type="button" aria-label="Tuesday 22 September 2026" aria-pressed="false" disabled>22</button>
<button class="cal-day" type="button" aria-label="Wednesday 23 September 2026" aria-pressed="false" disabled>23</button>
<button class="cal-day" type="button" aria-label="Thursday 24 September 2026" aria-pressed="false" disabled>24</button>
<button class="cal-day" type="button" aria-label="Friday 25 September 2026" aria-pressed="false" disabled>25</button>
<button class="cal-day cal-day--weekend" type="button" aria-label="Saturday 26 September 2026" aria-pressed="false" disabled>26</button>
<button class="cal-day cal-day--weekend" type="button" aria-label="Sunday 27 September 2026" aria-pressed="false" disabled>27</button>
</div>
<div class="cal-row">
<button class="cal-day" type="button" aria-label="Monday 28 September 2026" aria-pressed="false" disabled>28</button>
<button class="cal-day" type="button" aria-label="Tuesday 29 September 2026" aria-pressed="false" disabled>29</button>
<button class="cal-day" type="button" aria-label="Wednesday 30 September 2026" aria-pressed="false" disabled>30</button>
<span class="cal-day cal-day--outside"></span>
<span class="cal-day cal-day--outside"></span>
<span class="cal-day cal-day--outside"></span>
<span class="cal-day cal-day--outside"></span>
</div>
</div>
<div class="datepicker-actions">
<button class="btn btn-sm btn-ghost" type="button">Any time</button>
<button class="btn btn-sm" type="button" popovertarget="ft-deployed" popovertargetaction="hide">Cancel</button>
<button class="btn btn-sm btn-primary" type="button" popovertarget="ft-deployed" popovertargetaction="hide">Apply</button>
</div>
</div>
</th>
<th class="col-control" style="--col-control-min: 9rem">
<div class="segmented segmented--sm" role="group" aria-label="Filter by monitoring">
<label class="segmented-option"><input type="radio" name="ft-monitored" checked />Any</label>
<label class="segmented-option"><input type="radio" name="ft-monitored" />Yes</label>
<label class="segmented-option"><input type="radio" name="ft-monitored" />No</label>
</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>orders-console-01</td>
<td>Production</td>
<td>EU-West</td>
<td><span class="badge badge-go">Running</span></td>
<td class="col-num">42%</td>
<td class="col-muted">11 Sep 2026, 16:40</td>
<td>Yes</td>
</tr>
<tr>
<td>orders-console-02</td>
<td>Production</td>
<td>EU-Central</td>
<td><span class="badge badge-warn">Degraded</span></td>
<td class="col-num">91%</td>
<td class="col-muted">10 Sep 2026, 09:15</td>
<td>Yes</td>
</tr>
<tr>
<td>orders-api-04</td>
<td>Staging</td>
<td>EU-West</td>
<td><span class="badge badge-go">Running</span></td>
<td class="col-num">17%</td>
<td class="col-muted">9 Sep 2026, 14:02</td>
<td>No</td>
</tr>
<tr>
<td>orders-worker-07</td>
<td>Production</td>
<td>EU-Central</td>
<td><span class="badge badge-danger">Stopped</span></td>
<td class="col-num">0%</td>
<td class="col-muted">7 Sep 2026, 11:30</td>
<td>Yes</td>
</tr>
</tbody>
</table>
</div>
Several filters at once
With more than one filter set, repeat them above the table as .chip--active
chips, each removable on its own, and end the row with Reset all. The chips are
what a reader sees without scanning the filter row, and the count says how much the filters
took away. Every filtered heading says so to a screen reader too, in a
.visually-hidden span — the colour and the rule under it are not a label.
| Order | Customer | Status, filtered | Amount, filtered | Region, filtered |
|---|---|---|---|---|
|
Status
|
–
|
|||
| ORD-4209 | Alex Fischer | Open | 318.50 | EU-West |
| ORD-4204 | Priya Nair | Held | 142.00 | EU-West |
| ORD-4187 | Jordan Weiss | Open | 489.90 | EU-West |
| ORD-4182 | Alex Fischer | Open | 104.25 | EU-West |
| ORD-4176 | Priya Nair | Held | 276.00 | EU-West |
| ORD-4171 | Jordan Weiss | Open | 199.99 | EU-West |
<div class="toolbar">
<div class="toolbar-filters">
<span class="chip chip--active">
<span class="chip-label">Status: Open, Held</span>
<button class="chip-dismiss" type="button" aria-label="Remove the status filter"><i class="ri-close-line"></i></button>
</span>
<span class="chip chip--active">
<span class="chip-label">Amount: 100–500</span>
<button class="chip-dismiss" type="button" aria-label="Remove the amount filter"><i class="ri-close-line"></i></button>
</span>
<span class="chip chip--active">
<span class="chip-label">Region: EU-West</span>
<button class="chip-dismiss" type="button" aria-label="Remove the region filter"><i class="ri-close-line"></i></button>
</span>
<button class="btn btn-sm btn-ghost" type="button"><i class="ri-filter-off-line"></i> Reset all</button>
</div>
<div class="toolbar-actions">
<span class="toolbar-count">6 of 482 orders</span>
</div>
</div>
<div class="sedna-scroll" style="max-height:280px">
<table class="table table--sticky">
<thead>
<tr>
<th>Order</th>
<th>Customer</th>
<th class="col-filtered">Status<span class="visually-hidden">, filtered</span></th>
<th class="col-num col-filtered">Amount<span class="visually-hidden">, filtered</span></th>
<th class="col-filtered">Region<span class="visually-hidden">, filtered</span></th>
</tr>
<tr class="tr-filter">
<th class="col-control" style="--col-control-min: 8rem">
<div class="input-group input-group--sm">
<span class="input-affix"><i class="ri-search-line"></i></span>
<input class="form-input" type="search" placeholder="ORD-…" aria-label="Filter by order" />
<button class="input-clear" type="button" aria-label="Clear the order filter"><i class="ri-close-line"></i></button>
</div>
</th>
<th class="col-control" style="--col-control-min: 9rem">
<div class="input-group input-group--sm">
<span class="input-affix"><i class="ri-search-line"></i></span>
<input class="form-input" type="search" placeholder="Name" aria-label="Filter by customer" />
<button class="input-clear" type="button" aria-label="Clear the customer filter"><i class="ri-close-line"></i></button>
</div>
</th>
<th class="col-control col-filtered" style="--col-control-min: 8rem">
<button class="form-input form-input-sm form-trigger" type="button" popovertarget="fa-status" aria-label="Filter by status, 2 selected">
<span>2 selected</span>
</button>
<div class="popover" id="fa-status" popover>
<strong class="popover-title">Status</strong>
<div class="sedna-col">
<label class="form-check"><input type="checkbox" checked /> Open</label>
<label class="form-check"><input type="checkbox" checked /> Held</label>
<label class="form-check"><input type="checkbox" /> Shipped</label>
<label class="form-check"><input type="checkbox" /> Cancelled</label>
</div>
<div class="form-actions form-actions--split">
<button class="btn btn-sm btn-ghost" type="button">Clear</button>
<button class="btn btn-sm btn-primary" type="button" popovertarget="fa-status" popovertargetaction="hide">Apply</button>
</div>
</div>
</th>
<th class="col-control col-num col-filtered" style="--col-control-min: 8rem">
<div class="input-group input-group--sm">
<input class="form-input" type="number" value="100" placeholder="Min" aria-label="Lowest amount" />
<span class="input-affix">–</span>
<input class="form-input" type="number" value="500" placeholder="Max" aria-label="Highest amount" />
</div>
</th>
<th class="col-control col-filtered" style="--col-control-min: 8rem">
<select class="form-select form-select-sm" aria-label="Filter by region">
<option>Any</option>
<option selected>EU-West</option>
<option>EU-Central</option>
<option>US-East</option>
</select>
</th>
</tr>
</thead>
<tbody>
<tr><td>ORD-4209</td><td>Alex Fischer</td><td><span class="badge badge-info">Open</span></td><td class="col-num">318.50</td><td>EU-West</td></tr>
<tr><td>ORD-4204</td><td>Priya Nair</td><td><span class="badge badge-warn">Held</span></td><td class="col-num">142.00</td><td>EU-West</td></tr>
<tr><td>ORD-4187</td><td>Jordan Weiss</td><td><span class="badge badge-info">Open</span></td><td class="col-num">489.90</td><td>EU-West</td></tr>
<tr><td>ORD-4182</td><td>Alex Fischer</td><td><span class="badge badge-info">Open</span></td><td class="col-num">104.25</td><td>EU-West</td></tr>
<tr><td>ORD-4176</td><td>Priya Nair</td><td><span class="badge badge-warn">Held</span></td><td class="col-num">276.00</td><td>EU-West</td></tr>
<tr><td>ORD-4171</td><td>Jordan Weiss</td><td><span class="badge badge-info">Open</span></td><td class="col-num">199.99</td><td>EU-West</td></tr>
</tbody>
</table>
</div>
A filter in the header
For a table too narrow for a filter row, a .th-filter button at the end of the
heading opens the column's filter in a popover.
.th-filter--active fills it and adds a dot while the filter is set; say the same
in its aria-label. Beside a .th-sort, wrap the two in a
.sedna-row.sedna-gap-0. Open both.
| Order |
Status, filtered
Status
|
Placed
|
|---|---|---|
| ORD-4187 | Open | 14 Sep 2026 |
| ORD-4209 | Open | 12 Sep 2026 |
| ORD-4176 | Held | 9 Sep 2026 |
| ORD-4204 | Held | 8 Sep 2026 |
<div class="card" style="max-width:360px">
<table class="table">
<thead>
<tr>
<th>Order</th>
<th class="col-filtered">
<div class="sedna-row sedna-gap-0">
Status<span class="visually-hidden">, filtered</span>
<button class="th-filter th-filter--active" type="button" popovertarget="fp-status" aria-label="Filter by status, 2 chosen"><i class="ri-filter-3-line"></i></button>
<div class="popover" id="fp-status" popover>
<strong class="popover-title">Status</strong>
<div class="sedna-col">
<label class="form-check"><input type="checkbox" checked /> <span class="badge badge-info">Open</span></label>
<label class="form-check"><input type="checkbox" checked /> <span class="badge badge-warn">Held</span></label>
<label class="form-check"><input type="checkbox" /> <span class="badge badge-go">Shipped</span></label>
<label class="form-check"><input type="checkbox" /> <span class="badge badge-danger">Cancelled</span></label>
</div>
<div class="form-actions form-actions--split">
<button class="btn btn-sm btn-ghost" type="button">Clear</button>
<button class="btn btn-sm btn-primary" type="button" popovertarget="fp-status" popovertargetaction="hide">Apply</button>
</div>
</div>
</div>
</th>
<th aria-sort="descending">
<div class="sedna-row sedna-gap-0">
<button class="th-sort" type="button">Placed</button>
<button class="th-filter" type="button" popovertarget="fp-placed" aria-label="Filter by date placed"><i class="ri-filter-3-line"></i></button>
<div class="popover" id="fp-placed" popover>
<strong class="popover-title">Placed</strong>
<div class="sedna-col">
<div class="segmented segmented--sm" role="group" aria-label="Comparison">
<label class="segmented-option"><input type="radio" name="fp-placed-op" />Before</label>
<label class="segmented-option"><input type="radio" name="fp-placed-op" checked />On</label>
<label class="segmented-option"><input type="radio" name="fp-placed-op" />After</label>
</div>
<input class="form-input form-input-sm" type="date" aria-label="Date placed" />
</div>
<div class="form-actions form-actions--split">
<button class="btn btn-sm btn-ghost" type="button">Clear</button>
<button class="btn btn-sm btn-primary" type="button" popovertarget="fp-placed" popovertargetaction="hide">Apply</button>
</div>
</div>
</div>
</th>
</tr>
</thead>
<tbody>
<tr><td>ORD-4187</td><td><span class="badge badge-info">Open</span></td><td class="col-muted">14 Sep 2026</td></tr>
<tr><td>ORD-4209</td><td><span class="badge badge-info">Open</span></td><td class="col-muted">12 Sep 2026</td></tr>
<tr><td>ORD-4176</td><td><span class="badge badge-warn">Held</span></td><td class="col-muted">9 Sep 2026</td></tr>
<tr><td>ORD-4204</td><td><span class="badge badge-warn">Held</span></td><td class="col-muted">8 Sep 2026</td></tr>
</tbody>
</table>
</div>
Nothing found, and refreshing
.tr-empty is the row for a query that returned nothing, inside a table that is
still there with its toolbar and count; .tr-busy is the same row for a refresh
in flight. Write colspan="999", never the real count: a
browser clamps it to the columns the table has, so it spans them all and does not go stale
when a column is added. A .state-art drawing sits
centred above the text; the first load is skeleton rows instead.
| Order | Status | Owner | Lines | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| No order matches these filters. Clear one to see more. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Order | Status | Owner | Lines | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Refreshing orders… | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div class="sedna-col sedna-gap-3">
<table class="table">
<thead>
<tr><th>Order</th><th>Status</th><th>Owner</th><th class="col-num">Lines</th></tr>
</thead>
<tbody>
<tr class="tr-empty">
<td colspan="999">
<svg class="state-art state-art--sm" aria-hidden="true"><use href="#filtered-out" /></svg>
No order matches these filters. Clear one to see more.
</td>
</tr>
</tbody>
</table>
<table class="table">
<thead>
<tr><th>Order</th><th>Status</th><th>Owner</th><th class="col-num">Lines</th></tr>
</thead>
<tbody aria-busy="true">
<tr class="tr-busy">
<td colspan="999"><span class="spinner" aria-hidden="true"></span>Refreshing orders…</td>
</tr>
</tbody>
</table>
</div>
Stacked on a narrow screen
.table--stack turns each row into a card below 640px, taking each cell's label
from data-label; a cell without one — an actions cell — keeps the full width.
It throws away column alignment, so it is right for records read one at a
time and wrong for anything scanned down a column. Narrow this window to see it.
| Order | Group | Priority | |
|---|---|---|---|
| ORD-4209 | EU-Central | P3 | |
| ORD-4204 | EU-West | P1 |
<table class="table table--stack">
<thead><tr><th>Order</th><th>Group</th><th>Priority</th><th></th></tr></thead>
<tbody>
<tr>
<td data-label="Order">ORD-4209</td>
<td data-label="Group">EU-Central</td>
<td data-label="Priority"><span class="badge badge-warn">P3</span></td>
<td><button class="btn btn-sm" type="button">Open</button></td>
</tr>
<tr>
<td data-label="Order">ORD-4204</td>
<td data-label="Group">EU-West</td>
<td data-label="Priority"><span class="badge badge-danger">P1</span></td>
<td><button class="btn btn-sm" type="button">Open</button></td>
</tr>
</tbody>
</table>