Descriptions

A read-only list of label and value pairs, laid out as a grid, for the detail view of one record.

Accessibility

What Descriptions does for you, and what it leaves to the page around it.

What it renders

The root is a <div> around a real <table>, and every pair is a cell in it. There is no <caption>, no <thead> and no role, and screen readers announce it as a table.
  • A screen reader offers table navigation and announces the row and column count of the grid you laid out. Four items at column={3} are announced as a two-row table.
  • An aria-label on Descriptions lands on the outer <div>, not on the table. Put a real heading above the block instead.
  • The kit adds no markup of its own, so everything here is the same as in Ant Design.

Is the label tied to its value

It depends on the form you pick, and the plain horizontal form is the weakest of the three.
  • Horizontal, not bordered: the label and the value are two <span>s in one <td>. The table has no <th>, so a reader hears one cell whose text starts with the label. It reads fine in order and gives nothing to navigate by.
  • Horizontal and bordered: the label is a real <th> and the value its own <td>.
  • Vertical: the labels get their own row of <th> cells above the values, bordered or not.
  • No <th> gets a scope, so the browser guesses which cells a header belongs to. That works well for the vertical header row and less reliably for a horizontal one. Prefer bordered where the content matters, and test it in the screen readers you support.

Reading order when column reflows

A table is read row by row, and column decides what a row is. It changes at each breakpoint, so the grouping changes with the screen width.
  • On a phone the default is 1 column, so every pair is its own row and the reading order is the order of items. At 3 columns the first three items share a row. The order never changes, only the grouping.
  • Keep items in the order they should be read, and do not use span to move something visually away from where the reading order puts it.
  • The last item of a short row stretches to fill it. A reader loses nothing, and it is why the announced column count changes from one screen width to the next.
  • The vertical layout splits every pair across two rows, so a reader moving cell by cell hears all the labels, then all the values. Column navigation pairs them again. Keep column at 2 or 3 in the vertical form.

An empty value has to say so

An item whose children is null or undefined renders a cell with nothing inside it.
  • An empty cell is announced as blank or skipped. A reader cannot tell “no phone number on file” from “this row failed to load”.
  • Write the words: None, Not set, Not provided. Pick one and use it across the surface.
  • A grayed placeholder is still text someone has to read. Use a muted text color rather than opacity, and hold it to the same contrast as any other content.
  • Keep the item rather than dropping it. With more than one column, removing a pair moves everything after it, so two records of the same kind stop lining up.

Contrast and motion

  • Unbordered labels use labelColor, which defaults to colorTextTertiary. On white that is about 3.4:1, enough for large text and short of the 4.5:1 body text needs.
  • Bordered labels use colorTextSecondary on the shaded labelBg. That form is easier to read, and it is a second pair to check, because the text sits on the shade.
  • When the labels come out too faint, check colorTextTertiary in your theme first. The Tokens tab lists the rest.
  • A label is a label because of where it sits. Keep it that way when you restyle: a label told apart only by a lighter color disappears at low contrast.
  • There is no motion to manage. The only movement is the reflow when column crosses a breakpoint.