Menu


Description list


The facts about one thing, as rows of a name and its value, such as an account’s details or a record’s fields, with an optional action on each.

Customize the preview


Choices
Show
View

Contact details

Email address
ana.silva@example.com
Change Email address
Phone
Not provided
Change Phone
Date of birth
Hidden
Change Date of birth

Options


Description list options
ChoiceValuesDefaultWhat it does
layoutsmbk-description-list--layout-<value>stackedside-by-sidestacked
Stacked puts each value under its name; side by side gives the names a column of their own. Side by side stacks in a narrow space, unless small.
sizesmbk-description-list--size-<value>mdsmmd
Small is for a narrow panel, about 320 to 360 wide: the small text sizes and closer rows, and side by side the names take about a quarter of the row, so short values stay on one line.

Partssmbk-description-list__headingsmbk-description-list__rowssmbk-description-list__rowsmbk-description-list__termsmbk-description-list__valuesmbk-description-list__absentsmbk-description-list__iconsmbk-description-list__actionsmbk-description-list__hidden

Examples


Usage

Each value under its name, with a Change link a screen reader names after the row: "Change Email address".

Contact details

Email address
ana.silva@example.com
Change Email address
Phone
Not provided
Change Phone
Date of birth
Hidden
Change Date of birth

Side by side

The names in a column of their own, each value beside its name and the action at the end, on one line.

Contact details

Email address
ana.silva@example.com
Change Email address
Phone
Not provided
Change Phone
Date of birth
Hidden
Change Date of birth

Values that are not shown

A missing value says so in words, a hidden one says Hidden after its icon, and one still loading is a line of skeleton.

Billing

Plan
Team, paid yearly
Tax number
Not provided
Card
Hidden
Next payment
Loading

Rich values

A value can be a badge, a link or a sentence.

Site

Status
Live
Last published
Monday, 12 October, at 9:40

Without a heading

A short record on its own, with no heading over it.

Hull
Large
Speed
320

Small, in a narrow panel

Small, for a panel about 320 to 360 wide: the names take about a quarter of the row in the small label style, so each short value stays on one line beside its name.

Site

Short name
northwind
Contrast
4.1 : 1
Version
0.4.2
Theme
Light and dark
Published
Monday at 9:40
Change Published
Logo
Not provided

Guidelines


Purpose

The facts about one thing, as rows of a name and its value: an account's contact details, a record's fields, a site's settings at a glance. Each row can carry an action, such as a link to change the value. It differs from the list, which holds many things of one kind, and from the table, which compares many things across the same columns.

When to use

  • The details of an account, a person, an order or a site, read at a glance.
  • A summary to check before sending a form, each row with a way to change it.
  • A short record of a thing's properties, such as size and speed.

When not to use

  • Many things of the same kind. Use the list.
  • Many things compared across the same columns. Use the table.
  • Values to edit in place. Use fields in a form.

Usage rules

Do

  • Say a missing value in words.
  • Give each action a name of its own.
  • Use side by side where there is room for the names' column, and stacked in a narrow card.
  • Use small, side by side, in a narrow panel whose names and values are short, such as a tool's settings column.

Don't

  • Leave a value blank or put a dash in its place.
  • Show a secret value and hide it with style: leave it out of the page.
  • Use it for many things of one kind.
  • Use small for long names or long values: they wrap a word a line in a quarter of a narrow row.
Phone
Not provided
Do

Say a missing value in words, so the reader knows it is missing and not still loading.

Phone
—
Don't

A blank or a dash leaves the reader to guess whether the value is missing, hidden or broken.

Anatomy

  • The block, a div around everything.
  • The heading part, over the rows. Optional.
  • The rows part, a real dl.
  • The row part, a div inside the dl holding one name and its value.
  • The term part, the dt: the name of the value.
  • The value part, a dd: the value itself, which may be words, a link or a badge.
  • The absent part, inside the value, for a value that is not shown: the missing words, or the hidden words after the icon part.
  • The action part, a second dd holding a link, such as Change.
  • The hidden part: words for screen readers only, such as the name that follows Change.

Behavior

Stacked, each value sits under its name and the action under the value. Side by side, the names take a column of their own and each row ends with its action; the name, the value and the action share the line of their first words. Where the layout is narrow, side by side stacks before anything is cut off, and a long value wraps.

Two sizes. Medium, the default, is for a page, a card or a dialog. Small is for a narrow panel, such as a settings column about 320 to 360 pixels wide: the names and values take the small text sizes and the rows sit closer. Side by side and small, the names take about a quarter of the row, never less than their longest word, so a short value stays on one line beside its name; this form keeps its columns where the layout is narrow, since it is made for that space. The action links and the loading lines follow the size.

A value that is not given says "Not provided" in quieter words. A value that exists but is not shown here says "Hidden" after an eye icon, and nothing of the value is in the page. A value still loading is a line of skeleton as tall as the value, so nothing moves when it arrives. Each of these words can be changed.

Accessibility


What it does for you

  • It is a real description list: a screen reader reads each name with its value.
  • It takes no focus of its own. Each action link is a Tab stop.
  • A missing value is said in words, never shown as a blank or a dash.
  • A hidden value is never in the page, so it is not read; its icon is decoration and the word Hidden says it.
  • A value still loading is read as "Loading".
  • Side by side keeps the name before its value in the page, whatever the layout.

What you must do

  • Name each action for its row: words only a screen reader hears follow the visible ones, so a row of Change links reads "Change Email address", "Change Phone". Markup written by hand adds them in the hidden part.
  • Leave a secret value out of the page rather than hiding it with style.

How to test

  • With a screen reader, each name is read with its value, a missing value as words, a hidden one as "Hidden", and a loading one as "Loading".
  • Tab through the list: only the action links take focus, and each is read with its row's name.
  • With text at 200% and the page 320 pixels wide, the names and values stay whole and the layout stacks.
  • In a forced-color mode, the action links are still visible.

Keyboard

Description list keys
KeyWhat it does
Tab
Moves focus to the next action link.
Enter
Follows the focused action link.

Source


The files the description list is made of. Its folder on GitHub (opens in a new tab) holds them with its wrapper and its document.

Stylesheet
description-list.css
/* smbk-description-list — Description list. Figma "Description list" 7113:1025 and "Description list row"
 * 7113:941. A heading over rows of a term and its value, and an optional action. Stacked, the term sits over
 * its value and the action under it; side by side, the term has a column of its own and the action ends the
 * row. Side by side lines the three up on their first lines, so words of two sizes share one baseline. A value
 * that is not shown, missing or hidden, says so in quieter words; one still loading is a line of skeleton as
 * tall as the value, so nothing moves when it arrives. */

.smbk-description-list {
  display: flex;
  flex-direction: column;
  gap: var(--smbk-space-stack-lg);
  min-width: 0;
}

/* The block frames the words it hides for screen readers, so they stay inside it wherever it is placed: without a
   frame they hang from the page itself and stretch it, past the end of an area that scrolls. No weight, so a parent
   that places the block keeps its say. */
:where(.smbk-description-list) {
  position: relative;
}

.smbk-description-list__heading {
  margin: 0;
  color: var(--smbk-color-text-default);
  font-family: var(--smbk-typography-heading-2xs-font-family);
  font-size: var(--smbk-typography-heading-2xs-font-size);
  font-weight: var(--smbk-typography-heading-2xs-font-weight);
  line-height: var(--smbk-typography-heading-2xs-line-height);
  letter-spacing: var(--smbk-typography-heading-2xs-letter-spacing);
  text-transform: var(--smbk-typography-heading-2xs-text-transform);
}

.smbk-description-list__rows {
  display: flex;
  flex-direction: column;
  gap: var(--smbk-space-stack-xl);
  margin: 0;
  padding: 0;
}

.smbk-description-list__row {
  display: flex;
  flex-direction: column;
  gap: var(--smbk-space-stack-sm);
  min-width: 0;
}

.smbk-description-list__term {
  margin: 0;
  color: var(--smbk-color-text-subtle);
  font-family: var(--smbk-typography-label-md-font-family);
  font-size: var(--smbk-typography-label-md-font-size);
  font-weight: var(--smbk-typography-label-md-font-weight);
  line-height: var(--smbk-typography-label-md-line-height);
  letter-spacing: var(--smbk-typography-label-md-letter-spacing);
  text-transform: var(--smbk-typography-label-md-text-transform);
  overflow-wrap: break-word;
}

.smbk-description-list__value {
  min-width: 0;
  margin: 0;
  color: var(--smbk-color-text-default);
  font-family: var(--smbk-typography-body-md-font-family);
  font-size: var(--smbk-typography-body-md-font-size);
  font-weight: var(--smbk-typography-body-md-font-weight);
  line-height: var(--smbk-typography-body-md-line-height);
  letter-spacing: var(--smbk-typography-body-md-letter-spacing);
  overflow-wrap: anywhere;
}

/* A value that is not shown: "Not provided", or "Hidden" after its icon. Never a value in color alone. */
/* Its icon sits on the words' baseline, which centers the glyph on the capitals and keeps the row's line. */
.smbk-description-list__absent {
  display: inline-flex;
  align-items: baseline;
  gap: var(--smbk-space-inline-xs);
  color: var(--smbk-color-text-subtle);
}

.smbk-description-list__icon {
  flex: none;
  color: var(--smbk-color-icon-subtle);
  font-size: var(--smbk-size-icon-sm);
}

.smbk-description-list__action {
  flex: none;
  margin: 0;
}

/* .smbk-description-list__hidden: hidden from view, kept for screen readers and the keyboard, by the shared rule in visually-hidden/visually-hidden.css. */

/* ---- side by side: the term in a column of its own, the value filling the rest, the action at the end ---- */

.smbk-description-list--layout-side-by-side .smbk-description-list__rows {
  gap: var(--smbk-space-stack-lg);
}

.smbk-description-list--layout-side-by-side .smbk-description-list__row {
  flex-direction: row;
  align-items: baseline;
  gap: var(--smbk-space-inline-xl);
}

.smbk-description-list--layout-side-by-side .smbk-description-list__term {
  flex: none;
  width: var(--smbk-size-width-240);
}

.smbk-description-list--layout-side-by-side .smbk-description-list__value {
  flex: 1 1 0;
}

/* A value still loading has no line of text to line up by: it sits level with the term's line. */
.smbk-description-list--layout-side-by-side .smbk-description-list__value[aria-busy="true"] {
  align-self: flex-start;
}

/* A narrow space has no room for a column of names: the rows stack, keeping the term before its value. */
@container style(--smbk-layout: narrow) {
  .smbk-description-list--layout-side-by-side .smbk-description-list__rows {
    gap: var(--smbk-space-stack-xl);
  }

  .smbk-description-list--layout-side-by-side .smbk-description-list__row {
    flex-direction: column;
    align-items: stretch;
    gap: var(--smbk-space-stack-sm);
  }

  .smbk-description-list--layout-side-by-side .smbk-description-list__term {
    width: auto;
  }

  .smbk-description-list--layout-side-by-side .smbk-description-list__value {
    flex: none;
  }
}

/* ---- small: for a narrow panel, such as a settings column about 320 to 360 wide. The term in Label SM and the value in
   Body SM, the rows closer together. Side by side, the term takes about a quarter of the row and never less than its
   longest word, so a short value stays on one line beside it; the narrow layout keeps the columns, since the small
   form is made for that space. ---- */

.smbk-description-list--size-sm .smbk-description-list__rows {
  gap: var(--smbk-space-stack-lg);
}

.smbk-description-list--size-sm .smbk-description-list__row {
  gap: var(--smbk-space-stack-xs);
}

.smbk-description-list--size-sm .smbk-description-list__term {
  font-family: var(--smbk-typography-label-sm-font-family);
  font-size: var(--smbk-typography-label-sm-font-size);
  font-weight: var(--smbk-typography-label-sm-font-weight);
  line-height: var(--smbk-typography-label-sm-line-height);
  letter-spacing: var(--smbk-typography-label-sm-letter-spacing);
  text-transform: var(--smbk-typography-label-sm-text-transform);
}

.smbk-description-list--size-sm .smbk-description-list__value {
  font-family: var(--smbk-typography-body-sm-font-family);
  font-size: var(--smbk-typography-body-sm-font-size);
  font-weight: var(--smbk-typography-body-sm-font-weight);
  line-height: var(--smbk-typography-body-sm-line-height);
  letter-spacing: var(--smbk-typography-body-sm-letter-spacing);
}

.smbk-description-list--size-sm .smbk-description-list__icon {
  font-size: var(--smbk-size-icon-xs);
}

.smbk-description-list--size-sm.smbk-description-list--layout-side-by-side .smbk-description-list__rows {
  gap: var(--smbk-space-stack-sm);
}

.smbk-description-list--size-sm.smbk-description-list--layout-side-by-side .smbk-description-list__row {
  flex-direction: row;
  align-items: baseline;
  gap: var(--smbk-space-inline-md);
}

.smbk-description-list--size-sm.smbk-description-list--layout-side-by-side .smbk-description-list__term {
  flex: 0 0 25%;
  width: auto;
  min-width: min-content;
}

.smbk-description-list--size-sm.smbk-description-list--layout-side-by-side .smbk-description-list__value {
  flex: 1 1 0;
}

@container style(--smbk-layout: narrow) {
  .smbk-description-list--size-sm.smbk-description-list--layout-side-by-side .smbk-description-list__rows {
    gap: var(--smbk-space-stack-sm);
  }

  .smbk-description-list--size-sm.smbk-description-list--layout-side-by-side .smbk-description-list__row {
    flex-direction: row;
    align-items: baseline;
    gap: var(--smbk-space-inline-md);
  }

  .smbk-description-list--size-sm.smbk-description-list--layout-side-by-side .smbk-description-list__term {
    width: auto;
  }

  .smbk-description-list--size-sm.smbk-description-list--layout-side-by-side .smbk-description-list__value {
    flex: 1 1 0;
  }
}
Tokens it reads
Description list tokens
Token and CSSValuePreviewFoundation
space.stack.lg--smbk-space-stack-lgcomfortable: 16pxcompact: 12pxchanges with densitySpacing
color.text.default--smbk-color-text-defaultlight: #232527dark: #e7ebf0changes with themeColor
typography.heading-2xs--smbk-typography-heading-2xs-font-family--smbk-typography-heading-2xs-font-size--smbk-typography-heading-2xs-font-weight--smbk-typography-heading-2xs-line-height--smbk-typography-heading-2xs-letter-spacing--smbk-typography-heading-2xs-text-transformfontFamily: Funnel Display, Funnel Display Fallback, system-ui, sans-seriffontSize: min: 18px · max: 24pxfontWeight: 400lineHeight: 1.2letterSpacing: 0px

The quick brown fox

Typography
space.stack.xl--smbk-space-stack-xlcomfortable: 24pxcompact: 16pxchanges with densitySpacing
space.stack.sm--smbk-space-stack-smcomfortable: 8pxcompact: 6pxchanges with densitySpacing
color.text.subtle--smbk-color-text-subtlelight: #4e555edark: #9ba5b1changes with themeColor
typography.label-md--smbk-typography-label-md-font-family--smbk-typography-label-md-font-size--smbk-typography-label-md-font-weight--smbk-typography-label-md-line-height--smbk-typography-label-md-letter-spacing--smbk-typography-label-md-text-transformfontFamily: Geist, Geist Fallback, system-ui, sans-seriffontSize: 14pxfontWeight: 500lineHeight: 1.4letterSpacing: 0px

The quick brown fox

Typography
typography.body-md--smbk-typography-body-md-font-family--smbk-typography-body-md-font-size--smbk-typography-body-md-font-weight--smbk-typography-body-md-line-height--smbk-typography-body-md-letter-spacing--smbk-typography-body-md-text-transformfontFamily: Geist, Geist Fallback, system-ui, sans-seriffontSize: 16pxfontWeight: 400lineHeight: 1.5letterSpacing: 0px

The quick brown fox

Typography
space.inline.xs--smbk-space-inline-xs4pxSpacing
color.icon.subtle--smbk-color-icon-subtlelight: #4e555edark: #c4cdd8changes with themeColor
size.icon.sm--smbk-size-icon-sm16pxSize
space.inline.xl--smbk-space-inline-xlcomfortable: 16pxcompact: 12pxchanges with densitySpacing
size.width.240--smbk-size-width-240240pxSize
space.stack.xs--smbk-space-stack-xs4pxSpacing
typography.label-sm--smbk-typography-label-sm-font-family--smbk-typography-label-sm-font-size--smbk-typography-label-sm-font-weight--smbk-typography-label-sm-line-height--smbk-typography-label-sm-letter-spacing--smbk-typography-label-sm-text-transformfontFamily: Geist, Geist Fallback, system-ui, sans-seriffontSize: 12pxfontWeight: 500lineHeight: 1.4letterSpacing: 0px

The quick brown fox

Typography
typography.body-sm--smbk-typography-body-sm-font-family--smbk-typography-body-sm-font-size--smbk-typography-body-sm-font-weight--smbk-typography-body-sm-line-height--smbk-typography-body-sm-letter-spacing--smbk-typography-body-sm-text-transformfontFamily: Geist, Geist Fallback, system-ui, sans-seriffontSize: 14pxfontWeight: 400lineHeight: 1.5letterSpacing: 0px

The quick brown fox

Typography
size.icon.xs--smbk-size-icon-xs12pxSize
space.inline.md--smbk-space-inline-mdcomfortable: 8pxcompact: 6pxchanges with densitySpacing
Manifest
description-list.manifest.json
{
  "name": "description-list",
  "block": "smbk-description-list",
  "summary": "The facts about one thing, as rows of a name and its value, such as an account’s details or a record’s fields, with an optional action on each.",
  "adapt": "css",
  "axes": {
    "layout": {
      "values": [
        "stacked",
        "side-by-side"
      ],
      "default": "stacked",
      "description": "Stacked puts each value under its name; side by side gives the names a column of their own. Side by side stacks in a narrow space, unless small."
    },
    "size": {
      "values": [
        "md",
        "sm"
      ],
      "default": "md",
      "description": "Small is for a narrow panel, about 320 to 360 wide: the small text sizes and closer rows, and side by side the names take about a quarter of the row, so short values stay on one line."
    }
  },
  "flags": {},
  "parts": [
    "heading",
    "rows",
    "row",
    "term",
    "value",
    "absent",
    "icon",
    "action",
    "hidden"
  ],
  "figmaNodeId": "7113:1025"
}