Lists & tables
Lists and tables present data in one or more columns of rows.
When to use them
Use a list for navigation and single-column content. Use a table when people compare values across columns.
Preview
- Favorites
- › Documents
- › Downloads
- › Desktop
- › Screenshots
- Applications
- Network
| Name | Kind | Size |
|---|---|---|
| Report.pages | Document | 1.2 MB |
| Notes.txt | Plain text | 4 KB |
| Design | ||
| Mockups.fig | Design file | 48 MB |
| Icons.svg | SVG image | 96 KB |
Anatomy: list
A row is a 20px capsule with an 8px radius, on a 30px rhythm (5px block margin above and below). The label is 13px at weight 510. The disclosure chevron is 9px bold at 85% ink, in a 12px slot 9px from the capsule edge. Icons are 14px with a 2px radius. With a chevron and an icon, the icon starts 21px into the row and the label 41px. Each indent level adds 15px of leading padding.
| Class | Role |
|---|---|
.p-list | The row stack. Resets list styling. |
.p-list-row | One row. Flex container, radius 8px. |
.p-list-chevron | Disclosure slot, 9px bold at 85%. |
.p-list-icon | 14px icon slot, 6px before the label. |
.p-list-detail | Right-aligned secondary text. |
.p-list-group-title | Group heading, 11px at weight 590, 50% opacity. |
data-p-level="1..5" | Indentation, 15px per level. |
States: list
Selection uses a dedicated blue, #0165E2, darker than the control accent so white text holds contrast (5.3:1). All content in a selected row turns white, including the chevron and detail text.
| State | Class | Values |
|---|---|---|
| Rest | Text rgba(0, 0, 0, 0.85), no fill | |
| Hover | Fill rgba(0, 0, 0, 0.05) | |
| Selected, focused | .p-selected | Fill #0165E2, white text |
| Selected, inactive | .p-selected-quiet | Fill rgba(0, 0, 0, 0.14), text unchanged. Use when the containing view loses focus. |
| Dimmed | .p-dimmed or aria-disabled="true" | Text at 50%, no pointer events |
To retint the selection, override the token on the list: style="--p-list-selection: #AF52DE". Keep white text above 4.5:1 when you do.
Anatomy: table
Apply .p-table to a real <table>. Rows butt together on a dense 20px pitch, inset 10px from the table edge. There are no row hairlines. Instead, every other row is striped with an 8px-radius capsule at rgba(0, 0, 0, 0.05). The stripes count across group-title rows (tr.p-table-group), so the rhythm never breaks. Add .p-table-plain to turn the stripes off.
Cells are 13px at weight 510 with 8px horizontal padding. The first column reads at 85% ink and the others at 50%, so the name leads. Right-align numeric columns with .p-table-num.
The header is quiet: 19px cells in a 31px band, with no line under it. The sorted column is 11px bold at 85%, and the others are 11px at weight 510 at 50%. Column dividers are 1×19px at rgba(0, 0, 0, 0.1) on the leading edge of each column after the first, in the header only.
Sorting is declared, not styled by hand: set aria-sort="ascending" or descending on the sorted <th>. The column turns bold and its 9px chevron renders and flips. Screen readers announce the same attribute, so the visual and the announcement never drift apart.
A selected row (.p-selected on the <tr>) fills every cell in #0165E2 and rounds only the outer corners, 8px on the first and last cell. The row reads as one capsule spanning all columns. Use .p-selected-quiet when the table loses focus.
Dark mode
These values are derived rather than measured. Selection lifts to #0A6CF0, one step brighter in the same blue family, to hold against dark backgrounds. Stripes, hover and dividers become their white-alpha mirrors: stripes and hover rgba(255, 255, 255, 0.05), dividers rgba(255, 255, 255, 0.1), inactive selection rgba(255, 255, 255, 0.14). Text moves to rgba(255, 255, 255, 0.85), with secondary columns at 50%. Both .p-dark-mode and .p-auto-dark-mode are supported.
Code
<ul class="p-list">
<li class="p-list-group-title">Favorites</li>
<li class="p-list-row p-selected" aria-selected="true">
<span class="p-list-chevron">›</span>
<span class="p-list-icon"><img src="folder.png" alt="" /></span>
Downloads
<span class="p-list-detail">128</span>
</li>
<li class="p-list-row" data-p-level="1">Screenshots</li>
</ul>
<table class="p-table">
<thead>
<tr><th aria-sort="ascending">Name</th><th>Size</th></tr>
</thead>
<tbody>
<tr class="p-selected"><td>Mockups.fig</td><td>48 MB</td></tr>
</tbody>
</table>
For interactive lists give rows tabindex="0" and manage aria-selected. With prefers-contrast: more, the inactive selection gains a 1px outline so state never relies on the 14% fill alone, and table rows get a 1px rule so they don’t rely on the 5% stripes.