Published · Updated · v0.6.5 · MIT License · Source: list.md
List
Single-line
- Inbox
- Sent
- Drafts
- Trash
Ordered static
- 1. First item
- 2. Second item
- 3. Third item
Two-line
- Brunch this weekend? Ali Connors — I'll be in your neighborhood doing errands this weekend.
- Summer BBQ to Alex, Scott, Jennifer — Wish I could come, but I'm out of town this weekend.
Three-line
- Brunch this weekend? Ali Connors — I'll be in your neighborhood doing errands this weekend. Want to hang out?
- Summer BBQ to Alex, Scott, Jennifer — Wish I could come, but I'm out of town this weekend. Let me know if there is anything I can do.
Navigation
Selection
Leading & trailing icons
- Show your work
- Made for everyone
List is a continuous, vertical index of text and images. Use a list when people must scan, select, or navigate related rows — settings, actions, or collections. Gelium reimplements the Material 3 list over semantic HTML — the root is a real <ul>, <ol>, <nav>, or <menu>, and each item is a <li>. No component JavaScript: navigation items are real <a href> links, and selection items are native checkboxes in a real form.
Guidance
When to use
Use a list when people must scan, select, or navigate related rows — settings, actions, or collections.
When not to use
Do not use a list for dense columnar data that needs sorting, filtering and pagination. A Data table is built for that. For a single choice from many options, a Select collapses the list; for a compact command menu anchored to a trigger, use a Menu.
Usability
- Navigation items wrap a real link (
<li>→<a href>); selection items wrap a native checkbox in alabel. - Row heights are 56 px (one-line), 72 px (two-line), and 88 px (three-line) via the modifiers.
- Selection submits with a normal form — no JavaScript required for multi-select.
Accessibility
- Keep the native elements: the
<ul>/<li>carry list semantics, links are real anchors, checkboxes are native inputs. - Wrap the selection checkbox in its
labelso the whole row is clickable and the accessible name matches the on-screen text. - The state layer is decorative; state and selection are never communicated by color alone.
- Focus rings stay on the native link or checkbox (
:focus-visible).
See Choose the right control for the cross-component decision.
Anatomy
The root carries the ui-list class and paints the container surface. Each ui-list-item is a flex row with up to three slots: an optional leading element, the text content, and an optional trailing element.
<ul class="ui-list">
<li class="ui-list-item">
<span class="ui-list-item-icon" aria-hidden="true">[icon]</span>
<span class="ui-list-item-text">
<span class="ui-list-item-headline">Show your work</span>
<span class="ui-list-item-supporting">Supporting text</span>
</span>
<span class="ui-list-item-icon ui-list-item-icon--end" aria-hidden="true">[icon]</span>
</li>
</ul>
- Row —
ui-list-item, a56px(one-line) flex row with16pxhorizontal padding. The--two-line(72px) and--three-line(88px) modifiers raise the height. - Leading —
ui-list-item-icon, a24pxdecorative slot on the inline-start. Icons arearia-hiddenand unfocusable; visible text supplies the accessible name. - Text —
ui-list-item-textholds theui-list-item-headline(body-large, on-surface) and optionalui-list-item-supporting(body-medium, on-surface-variant). Three-line items clamp the supporting text to two lines. - Trailing —
ui-list-item-icon ui-list-item-icon--end, a24pxdecorative slot on the inline-end.
Content types
The roadmap requires a list to distinguish navigation, selection, and static content — Gelium ports each to native semantics.
- Static — a plain
<li class="ui-list-item">with text content. - Navigation — the item wraps a real link:
<li class="ui-list-item"><a class="ui-list-item-link" href="...">. The anchor fills the row and is the focusable element. - Selection — the item wraps a native checkbox in a
label:<li class="ui-list-item ui-list-item--select"><label class="ui-list-item-label"><input type="checkbox" ...>. The checked values submit with a normal form — no JavaScript required for multi-select.
States
The list covers rest, hover, focus-visible, active/pressed, selected (the checked checkbox), and disabled (on individual items). Hover and active paint the Material state layer (ui-list-item::before) at the shared --ui-state-* opacities. Focus rings land on the native link or checkbox, so keyboard users always see the target. Disabled items drop to 38% opacity and are non-interactive.
Design tokens
The --ui-list-* tokens are declared scoped to the root so the primitive works standalone, and the theme may override them globally.
| Token | Meaning |
|---|---|
--ui-list-container-color |
List container (surface) |
--ui-list-item-leading-space |
Inline-start padding (16px) |
--ui-list-item-trailing-space |
Inline-end padding (16px) |
--ui-list-item-icon-size |
Leading/trailing icon edge (24px) |
--ui-list-item-one-line-height |
One-line row height (56px) |
--ui-list-item-two-line-height |
Two-line row height (72px) |
--ui-list-item-three-line-height |
Three-line row height (88px) |
--ui-list-item-label-color |
Headline color (on-surface) |
--ui-list-item-supporting-color |
Supporting text color (on-surface-variant) |
--ui-list-item-icon-color |
Leading/trailing icon color |
--ui-list-item-hover-opacity |
Hover state layer opacity |
--ui-list-item-pressed-opacity |
Pressed state layer opacity |
--ui-list-item-focus-opacity |
Focus state layer opacity |
--ui-list-item-disabled-opacity |
Disabled row opacity |
Progressive enhancement
There is no list component JavaScript. Navigation and selection work with scripting disabled: links navigate normally, and the selection form submits the checked checkbox values with a standard GET/POST. Without the stylesheet the markup degrades to a plain <ul>/<ol> of list items.
Accessibility
- Keep the native elements: the
<ul>/<li>carry list semantics, links are real anchors, checkboxes are native inputs with their names and values. - Wrap the selection checkbox in its
labelso the whole row is clickable and the accessible name always matches the on-screen text. - The state layer is decorative; state and selection are never communicated by color alone. Hover changes the layer, selection flips the checkbox, focus shows a ring.
- Focus rings stay on the native link or checkbox (
:focus-visible), so keyboard users always see where the row focus is. - Decorative SVGs are
aria-hiddenandfocusable="false"; the visible text supplies the accessible name. - In forced-colors mode the container uses
Canvas, text usesCanvasText, links keepLinkText, and disabled rows drop toGrayText. Content and interactivity survive without color.
Keyboard
Because the interactive pieces are native, keyboard behavior comes for free: links activate with Enter, checkboxes toggle with Space. Tab order follows document order. There is no custom roving tabindex — the roadmap defers arrow-key list navigation until a platform gap is demonstrated.