Skip to content

Item

A row for lists: an avatar, a title with an optional description, and trailing content such as a time, a badge, a switch or a chevron. Rows sit in a card or stand alone, and every part is centered on the row.

Install

import "elements-kit/ui/styles.css";
import "elements-kit/ui/avatar/avatar.css";
import "elements-kit/ui/item/item.css";

API

<div class="x-card" data-size="3">
<ul class="unset" role="list" data-inset="fill" aria-label="Songs">
<li>
<a class="x-item" href="/songs/dreams" data-interactive>
<span class="x-avatar" data-size="3" aria-hidden="true">
<span class="x-avatar-fallback">FM</span>
</span>
<div class="x-item-content">
<span class="x-item-title" data-variant="compact">Dreams</span>
<span class="x-item-description">Fleetwood Mac</span>
</div>
<div class="x-item-trailing">
<time>4:17</time>
<svg class="x-item-chevron" aria-hidden="true">…</svg>
</div>
</a>
</li>
</ul>
</div>
PartFor
.x-avatarthe leading visual; give it the item’s data-size
.x-item-contentholds the title and description, takes the free width
.x-item-title, .x-item-descriptionone line each, truncated with an ellipsis; data-wrap wraps them; data-variant="compact" on the title keeps it the row’s size
.x-item-trailingvalues and controls at the end, --space-1 apart
.x-item-chevrona disclosure icon you place (e.g. arrow_forward_ios); 1em of the row’s text, muted, mirrored in RTL
.x-item-linkthe row’s link when the row also holds buttons
.x-item-hinthelper text below a card of items; give it the card’s data-size
AttributeValues
data-size1, 2 (default), 3; on the item or a parent .x-card
data-alignstart for tall rows
data-interactivehover and press backgrounds
data-separatora line under the row, from where its text starts; none under the last row
data-accentaccent text, e.g. a destructive action

Sizes

One spacing value per size pads the row and separates the avatar, the text and the trailing content, so the avatar sits in a square cell.

data-sizeAvatarSpacingRowTitleCompact titleDescription
12484012px regular10px medium10px
2 (default)3284814px regular12px medium12px
340126416px regular14px medium14px

Set data-size on the card to size every row inside; a row’s own data-size overrides it.

Compact titles

A title is one step larger than the row’s text, for a title that stands alone, like a setting or an action. Over a description, use data-variant="compact": the title keeps the row’s size in medium weight, and the description is the same size in a muted colour. Both lines together are exactly the avatar’s height, so rows with and without a description are the same height. Use it on every row of a list whose rows mostly have descriptions, so the titles read evenly.

<div class="x-item-content">
<span class="x-item-title" data-variant="compact">Dreams</span>
<span class="x-item-description">Fleetwood Mac</span>
</div>

Wrapping

Add data-wrap to a title or description to wrap it instead of truncating it, for long names or addresses.

<span class="x-item-description" data-wrap>12 Rue de la Paix, 75002 Paris, France</span>

Tall rows

Add data-align="start" to a row with a long description, like a message preview. The description wraps to three lines, the avatar moves to the top, and trailing content stays on the title line.

<a class="x-item" href="/messages/1" data-interactive data-align="start">…</a>

When the row opens something and also holds buttons, make the title the link with .x-item-link. The link covers the whole row, and trailing controls stay clickable above it. Pressing a trailing control doesn’t press the row.

<li class="unset x-item" data-interactive>
<span class="x-avatar" data-size="3">…</span>
<div class="x-item-content">
<a class="x-item-link x-item-title" data-variant="compact" href="/songs/dreams">Dreams</a>
<span class="x-item-description">Fleetwood Mac</span>
</div>
<div class="x-item-trailing">
<button class="unset x-button" data-variant="text" data-icon aria-label="More">…</button>
</div>
</li>

Use data-variant="text" for an icon button at the end: its negative margin lines its glyph up with chevrons and text in other rows.

Groups

Head a card with a label, and add helper text below it. data-separator on a row draws a line under it, starting where the text starts.

<div class="x-label" data-variant="group" data-size="3" id="settings">Settings</div>
<div class="x-card" data-size="3">
<ul class="unset" role="list" aria-labelledby="settings" data-inset="fill">
<li><a class="x-item" href="/wifi" data-interactive data-separator>…</a></li>
<li><label class="x-item" data-interactive data-separator>…</label></li>
<li><a class="x-item" href="/notifications" data-interactive>…</a></li>
</ul>
</div>
<p class="x-item-hint" data-size="3">Changes apply to all your devices.</p>

States

StateHow
Hover, pressdata-interactive
Selectedaria-current or aria-selected="true"
Destructivedata-accent="red"
Disabled:disabled, aria-disabled="true" or data-disabled

Accessibility

Put rows of the same kind (songs, messages, people) in a <ul role="list">, one row per <li>. Screen readers then announce the count and position. The role keeps that in Safari, which drops list semantics once unset removes the bullets. A row can be the <li> itself, or an <a>, <button> or <label> inside it.

Use the element that matches what the row does: <a> to navigate, <button> for an action, <label> around a switch or checkbox. Never put buttons inside a <button> or <a> row; use .x-item-link instead. Hide decorative avatars and chevrons with aria-hidden="true", and name icon buttons with aria-label.

See also