# DescriptionList One record’s fields, as a real
rather than a grid of divs. - Group: Surfaces - Import: `import { DescriptionList } from '@misoto22/design'` - Page: https://ui.misoto22.com/components/description-list/ - Related: table, card, timestamp ## When to reach for it One record seen from the front — a detail page, a summary panel. Several records seen from above is a Table. ## Anatomy - **List** (required) — The
. It is the element that carries the pairing: a grid of divs looks identical and tells a screen reader there are two columns of unrelated text. - **Pair** (required) — A
around each dt/dd, which the HTML specification allows inside a
precisely so a pair can be laid out as a unit. It is what the hairline is drawn on, so the rule crosses the whole row rather than stopping in the column gap. - **Term** (required) — item.term, rendered as
at --ink-3-aa. In the row layout it holds a 12rem column at sm and above and stacks below it, because a 12rem label column on a phone leaves the value about eight characters wide. - **Description** (required) — item.description, rendered as
at --ink-2 with its browser margin reset. It takes a node, not a string, so a value can be a Badge, a link or a Timestamp. - **Hairline** — divided, on by default: a --rule under every pair but the last. Turn it off inside a Card, which already has an edge of its own. ## Best practices ### Do - Let it render nothing when items is empty. It returns null rather than an empty bordered box, so the page above is free to show an EmptyState instead of a hairline around no content. - Put an element in description when the value is a state or a link — it is a
, so a Badge, an anchor or a Timestamp belongs there and a string of text does not have to be faked into one. - Pass id on each item when rows are added, removed or reordered. The index is the key without one, which is right for the fixed field list a record page renders and wrong for a list that changes shape. ### Don’t - Do not reach for it to show several records. Every dt would repeat down the page and a reader comparing two records has to hold both in their head — that is what a Table’s column headings exist to avoid. - Do not use layout="row" inside a narrow sidebar. It only collapses on the sm breakpoint, which is the viewport, not the container — a 12rem label column inside a 20rem panel leaves nothing for the value. Use layout="stacked" there. ## Accessibility - A real
,
and
, which is what tells a screen reader that a label names the value beside it. - Each pair is grouped in a
, which the specification permits inside a
and which assistive technology reads through. - An empty list renders null rather than an empty
, so nothing announces a list with no items in it. ## DescriptionList A record's fields: label, value, label, value. The single most repeated shape in any detail page, and the one most often hand-built out of a `
` grid — which loses the only thing the markup was carrying. A `
` tells a screen reader that "Owner" names the thing beside it; a grid of divs tells it there are two columns of unrelated text, and the reader has to infer the pairing from reading order alone. Reach for `Table` instead when there are several records. This is one record seen from the front; a table is many records seen from above. Each pair is wrapped in a `
` — which the HTML specification allows inside a `
` precisely so a pair can be laid out as a unit — so the hairline runs the full width of the row rather than stopping in the column gap. An empty `items` renders `null` rather than an empty bordered box. A record with no fields is a state the page above should be handling with an `EmptyState`, and a hairline around nothing looks like a component that failed to load. ### Props - `items` (required) — `DescriptionListItem[]`. The pairs, in the order they should read. An empty array renders nothing. - `layout` — `DescriptionListLayout` default `'row'`. How the value sits relative to its label. See DescriptionListLayout. - `divided` — `boolean` default `true`. Draws a hairline under every pair but the last. Off for a list inside a card that already has an edge, on for a list that is the page's structure. Also accepts: `HTMLAttributes`. ## Example — record fields ```tsx import { Badge, DescriptionList, Timestamp } from '@misoto22/design' Deployed }, { term: 'Last deploy', description: , }, ]} /> ``` ## Example — row and stacked ```tsx import { DescriptionList } from '@misoto22/design'
``` ## Example — a metadata rail ```tsx import { Badge, DescriptionList, Heading, Text, Timestamp } from '@misoto22/design'
ui.misoto22.com The documentation site for the design package. Statically exported, so every page is HTML on a CDN and the only JavaScript is the parts a reader touches.
```