Tables 1.2.0
Styled, accessible tables with striped rows, hover states, borders, compact sizing,
responsive wrappers, and contextual row colors.
Read this page in English
.velin-table styles are stable. Interactive sorting/filter/pagination via <velin-data-table> is also documented as stable in 1.2.0.
When to use
- Tabular data with column headers — start with
<table class="velin-table">and a<caption>or accessible name. - Add striped / hover / bordered / compact modifiers for scannability.
- Need sort, filter, or pagination? Wrap in
<velin-data-table>.
When not
- Do not use tables for page layout — use grid / flex utilities.
- Do not encode status with color alone on contextual rows — keep text labels.
- Skip interactive data-table when a static table (or a list) is enough.
Basic Table
Add .velin-table to any <table> for base styling including
padding, horizontal dividers, and proper alignment.
Include a <caption> (or another accessible name) so screen readers can identify the table.
<table class="velin-table">
<thead>
<tr><th>#</th><th>Name</th><th>Role</th></tr>
</thead>
<tbody>
<tr><td>1</td><td>Alice</td><td>Designer</td></tr>
<tr><td>2</td><td>Bob</td><td>Developer</td></tr>
<tr><td>3</td><td>Carol</td><td>Manager</td></tr>
</tbody>
</table>
| # | Name | Role |
|---|---|---|
| 1 | Alice | Designer |
| 2 | Bob | Developer |
| 3 | Carol | Manager |
Striped Rows
Add .velin-table--striped for alternating row backgrounds.
<table class="velin-table velin-table--striped">
<thead><tr><th>#</th><th>Product</th><th>Price</th></tr></thead>
<tbody>
<tr><td>1</td><td>Widget</td><td>$9.99</td></tr>
<tr><td>2</td><td>Gadget</td><td>$14.99</td></tr>
<tr><td>3</td><td>Doohickey</td><td>$4.99</td></tr>
<tr><td>4</td><td>Thingamajig</td><td>$19.99</td></tr>
</tbody>
</table>
| # | Product | Price |
|---|---|---|
| 1 | Widget | $9.99 |
| 2 | Gadget | $14.99 |
| 3 | Doohickey | $4.99 |
| 4 | Thingamajig | $19.99 |
Hoverable Rows
Add .velin-table--hover to highlight rows on mouse over.
<table class="velin-table velin-table--hover">
...
</table>
| # | City | Country |
|---|---|---|
| 1 | Berlin | Germany |
| 2 | Tokyo | Japan |
| 3 | Sydney | Australia |
Bordered Table
Add .velin-table--bordered for borders on all sides and cells.
<table class="velin-table velin-table--bordered">
<thead><tr><th>A</th><th>B</th><th>C</th></tr></thead>
<tbody>
<tr><td>1</td><td>2</td><td>3</td></tr>
<tr><td>4</td><td>5</td><td>6</td></tr>
</tbody>
</table>
| A | B | C |
|---|---|---|
| 1 | 2 | 3 |
| 4 | 5 | 6 |
Compact Table
Use .velin-table--compact to reduce cell padding by half for data-dense views.
<table class="velin-table velin-table--compact velin-table--striped">
...
</table>
| # | Item | Qty | Total |
|---|---|---|---|
| 1 | Apples | 12 | $3.48 |
| 2 | Oranges | 8 | $4.00 |
| 3 | Bananas | 6 | $1.50 |
| 4 | Grapes | 2 | $5.99 |
Responsive Tables
Wrap any .velin-table in a .velin-table-responsive container
to enable horizontal scrolling on small screens.
Use .velin-table-responsive-{breakpoint} to make it responsive only below a
specific breakpoint.
<div class="velin-table-responsive">
<table class="velin-table">
<thead>
<tr>
<th>#</th>
<th>Column A</th>
<th>Column B</th>
<th>Column C</th>
<th>Column D</th>
<th>Column E</th>
<th>Column F</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td><td>Data</td></tr>
</tbody>
</table>
</div>
| # | Column A | Column B | Column C | Column D | Column E | Column F |
|---|---|---|---|---|---|---|
| 1 | Data | Data | Data | Data | Data | Data |
| 2 | Data | Data | Data | Data | Data | Data |
Contextual Row Colors
Apply contextual classes to individual rows or cells for semantic coloring.
<table class="velin-table">
<tbody>
<tr class="velin-table--primary"><td>Primary</td><td>Row</td></tr>
<tr class="velin-table--success"><td>Success</td><td>Row</td></tr>
<tr class="velin-table--danger"><td>Danger</td><td>Row</td></tr>
<tr class="velin-table--warning"><td>Warning</td><td>Row</td></tr>
<tr class="velin-table--info"><td>Info</td><td>Row</td></tr>
</tbody>
</table>
| Primary | Contextual row |
| Success | Contextual row |
| Danger | Contextual row |
| Warning | Contextual row |
| Info | Contextual row |
Sorting, filtering and pagination
The classes above are static. Wrap the same <table class="velin-table"> in
<velin-data-table> to add sortable headers,
text filtering and pagination. It is progressive enhancement: the markup stays semantic and the table
remains readable without JavaScript.
<velin-data-table sortable page-size="10">
<table class="velin-table">
<caption>Team members</caption>
<thead>
<tr>
<th data-sort="text">Name</th>
<th data-sort="number">Commits</th>
<th data-sort="none">Actions</th>
</tr>
</thead>
<tbody>
<tr><td>Ada</td><td>128</td><td><a href="#">Edit</a></td></tr>
</tbody>
</table>
</velin-data-table>
A <caption> (or a label attribute) is required — a table without an
accessible name is unusable with a screen reader. See the
Data table reference for filter-input,
empty-text, the velin-data-table-* events, and the sort/filter/paginate API.
Accessibility
- Always provide an accessible name (
<caption>,aria-labelledby, or data-tablelabel). - Use
<th scope="col|row">for headers; keep markup semantic without JavaScript. - Row color modifiers are visual only — pair with text for meaning (AAA-oriented tokens help contrast, not semantics).
Related
- Data table — sort, filter, pagination
- Typography · Overflow
- Accessibility