Divider

A rule between things, horizontal or vertical, optionally carrying a title in the middle of it.

Accessibility

Divider renders one element with one role. The work is deciding whether that element should be in the accessibility tree at all, and making sure it is never the only thing carrying a meaning.

What it renders

One <div> with role="separator". It has no tab stop, no state and no keyboard behavior, so the work is deciding what that one element says, and to whom.
  • The role cannot be changed. A role you pass is overwritten without a warning. If you need different semantics, use a different element.
  • Other attributes reach the element: id, aria-hidden, aria-label and data-*.
  • With a title, the text sits inside the separator, in reading order, between the two things it divides.
  • Screen readers differ in how much of a separator they announce, and some skip it. Never rely on it to tell the reader something.

When it is decoration, hide it

Most dividers are decoration. They draw a grouping the markup around them already expresses, through headings, sections or list structure.
  • When the two sides are already a heading, a section, a card or two groups of a list, pass aria-hidden="true" to take the line out of the accessibility tree.
  • Hide it when deleting it would cost a sighted reader only a visual cue they can get another way.
  • Never hide one with a title. aria-hidden hides the words too.
  • Inside a Menu, pass { type: "divider" } in items instead of placing a Divider among the options.

A title stops it being decorative

A divider with children is content. On most surfaces its words are the only written record of the grouping it draws.
  • Leave it in the accessibility tree, and check that the title makes sense read on its own.
  • A divider's title is not a heading. It never joins the document outline and cannot be jumped to, so add a real heading where readers would want to navigate to that boundary.
  • A vertical divider drops its title. children only render on a horizontal line, and a vertical one logs a warning in development instead.
  • plain changes only the weight. Do not rely on it to tell anyone a section matters less.

A hairline against its own surface

The line is one lineWidth of colorSplit, a faint color meant to be seen without being noticed, which puts it near the contrast floor in both modes.
  • Check it against the surface behind it. Inside a card, a popover or a toolbar that is not the page background, and a line that shows on the page can vanish on a raised surface.
  • Check light and dark mode separately, since colorSplit has a value per mode.
  • A decorative line is not held to a text contrast ratio. A line that is the only thing marking a boundary should be, and usually needs a label as well.
  • The title is text, so it is held to the text ratio with or without plain.
  • variant="wave" is painted as a background, so forced colors mode can hide it. Never let the wave carry meaning.

Never the only thing separating two meanings

A line is gone in a screen reader that skips separators, in a text-only view, in forced colors mode and on a poor printer. Whatever it means has to be written down as well.
  • If crossing the line changes what the items mean (a different account, a destructive action), say so with a heading, a group label or a legend.
  • In a menu where a line is the only thing setting “Delete” apart from “Edit”, put the destructive item in its own labeled group.
  • Test it by deleting the divider. If the page still reads, it was decoration and you can hide it. If not, the missing information belongs in the markup.
  • Between two columns, reading order follows the markup, so the columns arrive one after the other. The grouping has to exist in the markup.