List

ul.list[role="list"]

List — the structured row list: a settings list, a file list, an inbox.

Examples

Rows with a control

View “Rows with a control” as
  • Wi-Fi Connect automatically to known networks
  • Bluetooth
<ul class="list list-divided" role="list">
  <li>
    <div class="list-content">
      <span class="list-title" id="wifi-label">Wi-Fi</span>
      <span class="list-support">Connect automatically to known networks</span>
    </div>
    <div class="list-trailing">
      <input class="switch" type="checkbox" role="switch"
             aria-labelledby="wifi-label" checked />
    </div>
  </li>
  <li>
    <div class="list-content">
      <span class="list-title" id="bt-label">Bluetooth</span>
    </div>
    <div class="list-trailing">
      <input class="switch" type="checkbox" role="switch" aria-labelledby="bt-label" />
    </div>
  </li>
</ul>

When the row holds its own control, the row itself is not interactive. A button inside a link is invalid HTML and a control inside a clickable row is a target inside a target.

Rows that are links

View “Rows that are links” as
<ul class="list list-divided" role="list">
  <li>
    <a class="list-action" href="#report">
      <span class="list-content">
        <span class="list-title">quarterly-report.pdf</span>
        <span class="list-support">2.4 MB · edited yesterday</span>
      </span>
      <span class="list-trailing">Shared</span>
    </a>
  </li>
  <li>
    <a class="list-action" href="#notes">
      <span class="list-content">
        <span class="list-title">notes.md</span>
      </span>
    </a>
  </li>
</ul>

.list-action goes on the <a> and is the row: it carries the padding, the hover and the focus ring, so the whole width is the target. The <li> becomes a bare wrapper.

Tokens 20

Level 2, declared on .list itself. Set any of them on that selector to restyle this component without touching the skin.

Level 2 tokens declared by list
TokenDefault
--list-action-current-colorvar(--color-primary)
--list-action-hover-bgvar(--color-surface-sunken)
--list-action-radiusvar(--radius-field)
--list-content-gapvar(--space-1)
--list-divider-colorvar(--color-border-subtle)
--list-divider-widthvar(--border-width)
--list-leading-colorvar(--color-on-surface-muted)
--list-row-aligncenter
--list-support-colorvar(--color-on-surface-muted)
--list-support-font-sizevar(--font-size-xs)
--list-title-colorvar(--color-on-surface)
--list-title-font-sizevar(--font-size-sm)
--list-title-font-weightvar(--font-weight-medium)
--list-trailing-colorvar(--color-on-surface-muted)
--list-trailing-font-sizevar(--font-size-sm)
--list-trailing-gapvar(--space-2)
--list-row-gapvar(--space-3)
--list-row-min-size3rem
--list-row-padding-blockvar(--space-3)
--list-row-padding-inlinevar(--space-4)

Variants and states

Variants

  • .list-divided
  • .list-lg
  • .list-sm

Inside it

  • .list-action
  • .list-title
  • .list-content
  • .list-leading
  • .list-spaced
  • .list-support
  • .list-trailing

State it reads

Read from the platform, never mirrored into a class that could disagree with it.

  • :disabled
  • :focus
  • :hover

Before you ship it

What you have to do 1 requirements

  1. Put role="list" on the list. The reset strips markers from any <ul> or <ol> that carries a class, and in WebKit that also drops the list semantics: VoiceOver stops announcing "list, 8 items" and reads eight unrelated lines instead. role="list" restores it. This is not optional decoration — it is the one attribute without which the component is worse than a bare <ul>. Use <ol class="list" role="list"> where the order is meaningful; the role is the same. Name a trailing control from the row. A switch or checkbox in .list-trailing has no visible label of its own — the row's title is its label. Point at it: aria-labelledby="the-title-id", or wrap the title in a <label for>. Without this the control announces as "switch" and nothing else. Nothing in CSS can supply it. An icon in .list-leading is decoration. aria-hidden="true" on the <svg>; the row's text is the name.

src/css/components/list.css · npx mostlycss add list