Divider

A hairline that separates items in a list or groups in a menu — decorative by default, a semantic separator when it carries meaning.

Basic usage

Install the package:

pnpm add @design-schema/react @design-schema/tokens

Import the stylesheet once for the app, then the component:

import '@design-schema/tokens/calm-precise/css';
import '@design-schema/react/index.css';
import { Divider } from '@design-schema/react';

Examples

Today

Earlier

import { Divider } from '@design-schema/react';

<Divider />

Props

4 rows
PropTypeDefaultDescriptionPlatforms
orientationhorizontal | verticalhorizontal

Vertical dividers sit between inline siblings (toolbar groups) and stretch to the row height: inline-block with `block-size: auto; align-self: stretch; min-block-size: 100%` (flex stretch applies only to an auto cross size, and the min fills a parent with a set height). They need a flex or grid row (a horizontal Stack with align stretch) or a parent with a definite height; in plain block flow a vertical divider has no height and draws nothing.

web, lit, rn, swiftui
labelstring—

Optional text in the middle of a horizontal divider ("or", "Earlier today"). Turns the divider from decorative into a labelled separator (`semantic` is implied). Ignored on a vertical divider, with a development warning: a vertical line has no room for centered text. An ignored label implies nothing either — a vertical divider is semantic only when `semantic` says so. An empty string is no label: the divider stays decorative and nothing warns. On Lit `label` is a property that also reads the `label` attribute and does not reflect. The development warning fires when the ignored combination appears or changes (an effect keyed on `label` and `orientation`), not on every render; on React Native a vertical divider with an ignored label and `semantic: true` gets both warnings. Those warnings are development diagnostics, not `copy.*` strings: their wording is not contractual and may differ between platforms. A vertical divider with an ignored label and `semantic: true` is a separator with no accessible name on every platform — naming it from text that is not rendered would contradict the label being ignored. When in effect, the label is the separator's accessible name (see the platform notes), and the two line pieces on either side are hidden from assistive technology.

web, lit, rn, swiftui
semanticbooleanfalse

Expose as a separator to assistive technology. Leave false for purely visual lines between list rows; set true (or provide a label) when the divider marks a real boundary between sections that a screen-reader user should hear.

Accessibility: false → aria-hidden / hidden from AT; true → role=separator with aria-orientation.

web, lit, rn, swiftui
spacingnone | tight | normal | loosenone

Space on both sides along the cross axis (above and below a horizontal divider, left and right of a vertical one), from the layout rhythm, for dividers used outside a Stack that already spaces them. The space is transparent: web and Lit use margin-block (horizontal) or margin-inline (vertical); React Native pads the root View on that axis (paddingVertical or paddingHorizontal) with the line as an inner View. It applies to a labelled divider too, where the root is the row: the space is around the whole divider, label included, not around each line piece.

web, lit, rn, swiftui

Accessibility

Implicit ARIA role: separator.

Anatomy

linelabel

What generation guarantees

Contrast — Text and meaningful non-text contrast meets WCAG AA; the pairs are listed below.

Contrast pairs

1 row
ForegroundBackgroundLevel
color.foreground.mutedcolor.backgroundAA

This component does not animate, so it has no reduced-motion behaviour to describe.