Skip to main content

Item

A row with media, a title, a description and actions.

In Content first

See it live​

Start Storybook to see it live: npm run storybook

When to use it​

In Content first: Rows in the reading list, each with an action named in a word. Not where cards preview articles.

  • Use it when: Lists of things such as people, files or settings, each with a few actions.
  • Not when: Records people compare cell by cell (a table).

Instead:

  • Card: A larger unit with more content.
  • Table: Records compared across columns.

Variants​

What each variant is for in any design system, then what Content first decided and why. Each sample is the live story with that variant set.

defaultvariantUsed in Content first
Start Storybook to see it live

What it is for

No border and no fill: the row sits on the surface around it.

✓Lists inside a card, panel or menu that already has a frame.
✕Rows that stand alone on the page and need edges.

In Content first

Rows in the reading list, separated by space, not lines.

outlinevariantNot used in Content first
Start Storybook to see it live

What it is for

A border around each row.

✓Rows that stand alone on the page, such as a list of settings.
✕Long lists inside a framed panel, where borders add noise.

In Content first

Borders would interrupt reading; space separates the rows.

mutedvariantNot used in Content first
Start Storybook to see it live

What it is for

A soft fill behind the row.

✓A row that should stand out quietly, such as the current one.
✕Every row in a long list.

In Content first

Every row in the reading list weighs the same; attention belongs to the text.

defaultsizeUsed in Content first
Start Storybook to see it live

What it is for

Comfortable padding.

✓Most lists.
✕Dense panels with many short rows.

In Content first

Every row, at touch size: many readers are on phones.

smsizeNot used in Content first
Start Storybook to see it live

What it is for

Tighter padding.

✓Dense panels and short rows.
✕Touch screens and lists people read slowly.

In Content first

Many readers are on phones, and rows are read, not scanned.

Why it works this way​

Item looks the way it does because of 5 answers about this product. Each card is one answer, in three steps: the answer, what it decided for Item, and what would move if it changed.

What separates groups on the page?elevation.definition
1The answer
Space

Space separates groups; lines would interrupt reading.

2So Item
  • ✓uses default: Rows in the reading list, separated by space, not lines.
  • –does not use outline: Borders would interrupt reading; space separates the rows.
3If it changed
2
Item decisions would reopen

No other answer follows from it.

How dense is the layout?spacing.values
1The answer
Spacious

Room around the text helps reading.

2So Item
  • ✓uses default: Rows in the reading list, separated by space, not lines.
3If it changed
1
Item decision would reopen

No other answer follows from it.

What must the interface protect?human.q1
1The answer
Attention on the content

Attention belongs to the text.

2So Item
  • –does not use muted: Every row in the reading list weighs the same; attention belongs to the text.
It also shapes Button: large Field: horizontal Empty: default
3If it changed
1
Item decision would reopen

and 8 answers that follow from it: Surface, text, action and status, Only what floats, One, and 5 more.

What is the smallest target?accessibility.values
1The answer
Touch size

Readers are often on phones.

2So Item
  • ✓uses default: Every row, at touch size: many readers are on phones.
  • –does not use sm: Many readers are on phones, and rows are read, not scanned.
It also shapes Button: default Button: compact
3If it changed
2
Item decisions would reopen

and 1 answer that follow from it: Those and pressed.

What is the main task?tasks.q1
1The answer
Read start to end

People read from start to end.

2So Item
  • –does not use sm: Many readers are on phones, and rows are read, not scanned.
3If it changed
4
Item decisions would reopen

and 23 answers that follow from it: Rarely, Attention on the content, Reading comfort, and 20 more.

Words​

  • Write to one person: "you", not "users".
  • Short sentences with room to breathe.
  • Explain why before asking for anything.
  • Use: Read, Save for later, You, Next issue. Avoid: Click here, Submit, Users, Content.

The labels components use, from the voice tokens:

  • content.action.commit: Save
  • content.action.cancel: Not now
  • content.action.destroy: Remove
  • content.action.retry: Try again
  • content.action.empty-action: Browse guides

See Voice and tone for the whole voice.

Use it in code​

npx open-ds add item

The component reads only component keys and semantic tokens, so it follows the brand and mode on <html>.

Tokens it reads​

Item reads 32 tokens of its own, each an alias of a semantic token. Each row is one part: its own token, the semantic it aliases, and the value it ends at. Change a semantic and every component that reads it follows; override one of Item's tokens to change Item alone.

Changes with theme

Content first decides what changes when you switch theme. Here a switch changes colors only, so the marked rows differ between light and dark; everything else holds steady.

PartIts token and the semantic it aliasesValue
Item
Cornercomponent.item.radiusradius.controlvar(--item-radius)radius.8:0.5rem
Text sizecomponent.item.font-sizetype.body.font-sizevar(--item-font-size)font.size.18:1.125rem
Speedcomponent.item.durationmotion.duration.feedbackvar(--item-duration)duration.moderate:200ms
Border focus
Changes with theme
on focus
component.item.border-focuscolor.border.focusvar(--item-border-focus)Lightnavy.light.600:#1E3A5FDarknavy.dark.600:#8FA6C4
Background hover
Changes with theme
on hover
component.item.background-hovercolor.surface.sunkenvar(--item-background-hover)Lightstone.light.100:#F6F2EADarkstone.dark.100:#2E2A24
Focus
on focus
component.item.focusborder-width.focusvar(--item-focus)border-width.2:2px
Focus ring focus
Changes with theme
on focus
component.item.focus-ring-focuscolor.border.focusvar(--item-focus-ring-focus)Lightnavy.light.600:#1E3A5FDarknavy.dark.600:#8FA6C4
Focus ring offset focus
Changes with theme
on focus
component.item.focus-ring-offset-focuscolor.surface.canvasvar(--item-focus-ring-offset-focus)Lightstone.light.50:#FFFDF8Darkstone.dark.0:#14110D
Gapcomponent.item.gapspace.gap.defaultvar(--item-gap)space.16:1rem
Outline
Border
Changes with theme
component.item.outline.bordercolor.border.defaultvar(--item-outline-border)Lightstone.light.200:#E4DDD0Darkstone.dark.100:#2E2A24
Muted
Fill
Changes with theme
component.item.muted.backgroundcolor.surface.sunkenvar(--item-muted-background)Lightstone.light.100:#F6F2EADarkstone.dark.100:#2E2A24
Default
Gapcomponent.item.default.gapspace.gap.groupvar(--item-default-gap)space.32:2rem
Paddingcomponent.item.default.paddingspace.inset.containervar(--item-default-padding)space.24:1.5rem
Sm
Gapcomponent.item.sm.gapcomponent-spacing-map.x3var(--item-sm-gap)space.20:1.25rem
Padding, left and rightcomponent.item.sm.padding-xspace.inset.containervar(--item-sm-padding-x)space.24:1.5rem
Padding, top and bottomcomponent.item.sm.padding-ycomponent-spacing-map.x3var(--item-sm-padding-y)space.20:1.25rem
Icon
Sizecomponent.item.icon.sizesize.control.defaultvar(--item-icon-size)size.48:3rem
Cornercomponent.item.icon.radiusradius.badgevar(--item-icon-radius)radius.999:9999px
Fill
Changes with theme
component.item.icon.backgroundcolor.surface.sunkenvar(--item-icon-background)Lightstone.light.100:#F6F2EADarkstone.dark.100:#2E2A24
Icon sizecomponent.item.icon.icon-sizesize.iconvar(--item-icon-icon-size)size.16:1rem
Image
Cornercomponent.item.image.radiusradius.badgevar(--item-image-radius)radius.999:9999px
Content
Gapcomponent.item.content.gapspace.gap.tightvar(--item-content-gap)space.8:0.5rem
Title
Gapcomponent.item.title.gapspace.gap.defaultvar(--item-title-gap)space.16:1rem
Text sizecomponent.item.title.font-sizetype.body.font-sizevar(--item-title-font-size)font.size.18:1.125rem
Weightcomponent.item.title.font-weighttype.label.font-weightvar(--item-title-font-weight)font.weight.600:600
Description
Text sizecomponent.item.description.font-sizetype.body.font-sizevar(--item-description-font-size)font.size.18:1.125rem
Weightcomponent.item.description.font-weighttype.body.font-weightvar(--item-description-font-weight)font.weight.400:400
Text
Changes with theme
component.item.description.labelcolor.text.mutedvar(--item-description-label)Lightstone.light.600:#61594DDarkstone.dark.400:#A39A8B
Label 2
Changes with theme
component.item.description.label-2color.action.primaryvar(--item-description-label-2)Lightnavy.light.600:#1E3A5FDarknavy.dark.600:#8FA6C4
Actions
Gapcomponent.item.actions.gapspace.gap.defaultvar(--item-actions-gap)space.16:1rem
Header
Gapcomponent.item.header.gapspace.gap.defaultvar(--item-header-gap)space.16:1rem
Footer
Gapcomponent.item.footer.gapspace.gap.defaultvar(--item-footer-gap)space.16:1rem
From the system
Edge
Changes with theme
color.border.default
straight from the system, through --border
Lightstone.light.200 · #E4DDD0Darkstone.dark.100 · #2E2A24