Display
Separator
A rule, in the three weights a monochrome page needs — with words in it when the break has something to say.
Usage
When to reach for it
import { Separator } from '@misoto22/design'Notes
A rule, with or without words in it.
In a monochrome system the rule does the work colour would otherwise do, so it has three weights rather than one: hairline between rows, edge between blocks, hard under a masthead. Picking by name keeps a page from drifting into five hand-tuned greys.
On the label. "or continue with" was two Separators and a span at every call site, and the usual one-element version — text laid over a single rule with a background to punch a hole in it — needs to know the ground it is sitting on. Get that wrong and the notch is --paper on a card that is --stone, which reads as a rendering bug. So there is no ground: the rule is drawn twice, one piece either side of the label, and the gap is a gap. It is correct on any surface without being told which one it is on.
Anatomy
| Element | Description |
|---|---|
| Rulerequired | One <div>. A pixel on its cross axis and 100% on its main axis, so it takes the width — or the height — of whatever contains it, and nothing else. |
| Inkrequired | The only thing weight changes: --rule inside a block, --rule-2 between blocks, --rule-hard under a masthead. The hard one is not a darker grey, it is --ink itself. |
| Label | label, horizontal only. It changes the construction rather than the styling: the rule is drawn TWICE, one aria-hidden piece either side of the words in mono-meta at --ink-3-aa, and the gap between them is a gap. |
Best practices
Do
- Give a vertical separator a height. It is h-full, which against a parent with no height of its own resolves to zero — the element renders, occupies nothing, and reads as a component that failed to load.
- Pass decorative={false} when the rule is the only thing dividing two sections a screen reader should hear as distinct: that is what swaps role="none" for role="separator" and sets aria-orientation with it.
- Use label rather than building "or continue with" out of two Separators and a span. The two rules are drawn for you and neither of them needs to know the ground it is on.
Don’t
- Do not pick the weight by eye. The three are ordered, so a hard rule between two table rows tells the reader the table ended there.
- Do not hand-tune a fourth grey through className. Three named weights are the whole set, and the names exist because a monochrome page drifts into five slightly different rules the moment one of them is chosen by feel.
- Do not lay the label over a single rule with a background colour to punch a hole in it. That version has to be told the ground it is sitting on, and a --paper notch on a --stone card reads as a rendering bug.
Examples
weights
The three weights, in the order they are meant to be spent. They are ordered rather than interchangeable, so a hard rule between two table rows tells the reader the table ended there — and the hard one is not a darker grey, it is --ink itself. Three named weights are the whole set; a fourth grey tuned by eye through className is how a monochrome page drifts.
vertical needs a height
A meta row divided by vertical rules. The vertical form is h-full, which against a parent with no height of its own resolves to zero — the element renders, occupies nothing, and reads as a component that failed to load. Give it a height, as here, or a row that stretches its children.
announced between sections
The rule that is doing real work. decorative={false} swaps role="none" for role="separator" and sets aria-orientation with it, so a screen reader hears the two sections as distinct. Reach for it only where the rule is the ONLY thing dividing them — a page that announces every hairline between its rows is read out as a list of separators.
Installation
One package, and one stylesheet next to it.
Upgrading
Minor versions add exports; they never move one.
words in the rule
Words in the break. label changes the CONSTRUCTION rather than the styling: the rule is drawn twice, one piece either side of the words, and the gap is a gap — so it is right on any ground without being told which one it is on. The usual one-element version lays the text over a single rule and punches a hole in it with a background colour, which is --paper on a card that is --stone and reads as a rendering bug. Horizontal only, and decorative stops applying, because the words are content.
Accessibility
- role="none" by default. A rule that only groups things visually must not be announced.
- With a label, the words are the content and the two rules are aria-hidden decoration — so decorative no longer applies, and nothing announces a separator over the top of the text.
- A label on a vertical rule is ignored rather than silently redrawn as a horizontal bar: there is no sensible place for words inside a one-pixel column.