Key-value list

Summary

Description-list styling for the detail-pane staple: one entity's facts as label/value pairs. Semantic <dl> markup: each <dt> names a fact (muted), its <dd> holds the value (badges, code and links all welcome). Two-column grid by default; -vertical stacks each pair for narrow panes. Row padding follows the density tokens, so detail panes tighten with data-soma-density like table rows.

When to use

PatternUse it for
Key-value listONE entity's facts, read-only: deployment metadata, entity detail panes, "About" panels, drawer summaries.
TableMANY entities with comparable columns — sortable if the operator reorders them.
Horizontal formThe values are EDITABLE: labels in a fixed column beside controls.
List groupRows that navigate or act — settings lists, pick lists.

Examples

Two-column (default)

The label column hugs its widest label; values take the rest — badges and code compose freely:

Service
nware-portal
Region
us-east
Tier
production
Status
healthy
Owner
platform-team
Last deployed
2026-07-30 14:12 UTC

Vertical

.soma-kv-vertical stacks each pair, for drawers, sidebars and other narrow panes:

Endpoint
https://api.nware.io/v2
Region
us-east
Status
healthy

Multiple values per key

Native dl semantics: one dt may be followed by several dd rows:

Service
soma-cdn
Regions
us-east
us-west
us-east
Owner
platform-team

Long content

Labels wrap at the column cap (--soma-kv-label-max, 220px); unbroken values wrap instead of overflowing:

Container image digest
sha256:9f2e1c74a0b6d8e3f5a1c9b7d2e4f6a8c0b2d4e6f8a0c2e4b6d8f0a2c4e6b8d0
Notes
Rolled forward after the 14:02 incident; canary held at 5% for two hours before full rollout.

Label column

The default grid is fit-content(var(--soma-kv-label-max)) minmax(0, 1fr): the label column hugs the widest <dt> up to the cap (220px), then wraps. Override the custom property per instance when a pane's labels run unusually long or short:

/* A cramped drawer pane — tighter label cap: */
.deploy-drawer .soma-kv {
  --soma-kv-label-max: 120px;
}

Values sit in a minmax(0, 1fr) column with overflow-wrap: anywhere, so an unbroken digest or URL wraps instead of blowing the pane open. Rows align on the text baseline (labels are 13px, values 14px).

Composition

The natural hosts are a widget body, a drawer or a dialog, anywhere a selection's detail renders. Values are free markup: <code> chips, badges, links, timestamps. Because the markup is a real <dl>, screen readers announce each pair as term and definition, and one <dt> may carry several <dd> values. Keep it read-only — the moment a value becomes editable, reach for the horizontal form instead.

HTML

The default two-column list:

<dl class="soma-kv">
  <dt>Region</dt><dd>us-east</dd>
  <dt>Tier</dt><dd>production</dd>
  <dt>Status</dt><dd><span class="soma-badge soma-badge-success">healthy</span></dd>
</dl>

Stacked pairs for narrow panes:

<dl class="soma-kv soma-kv-vertical">
  <dt>Endpoint</dt><dd><code>https://api.nware.io/v2</code></dd>
  <dt>Region</dt><dd>us-east</dd>
</dl>

Multiple values under one key:

<dl class="soma-kv">
  <dt>Regions</dt>
  <dd>us-east</dd>
  <dd>us-west</dd>
</dl>

CSS classes

ClassEffect
.soma-kvOn the <dl>: a two-column grid. <dt> is muted medium 13px in a fit-content label column, <dd> takes the rest and wraps long values. Row padding from --soma-density-cell-y.
.soma-kv-verticalStacks each pair, label above value, for narrow panes.
--soma-kv-label-maxCustom property on .soma-kv (default 220px): the label column's wrap cap. Override per instance.

JavaScript

None — the key-value list is CSS-only over a native <dl>. Render it server-side or build it from data like any markup.