Separator
A dividing line between two groups of content, announced as one.
Separator is the line you draw between two groups of content, rendered as a
role="separator" so a screen reader announces the division too. Useful
between the sections of a settings page, or between the actions in a toolbar,
where a bare border would show the division to sighted readers only.
A separator takes no space of its own, so give it a size on the axis it divides.
A vertical one needs a height as well, which in a flex row is usually self-stretch.
<template>
<div class="flex w-full max-w-md flex-col gap-6">
<div class="flex items-center gap-2" role="group" aria-label="Document">
<Button v-for="action in actions" :key="action" :class="button">
{{ action }}
</Button>
<Separator orientation="vertical" :class="vertical" />
<Button :class="button">Delete</Button>
</div>
<div class="flex flex-col gap-4">
<p class="type-surface-body-sm text-surface-muted">
A separator takes no space of its own, so give it a size on the axis it
divides.
</p>
<Separator :class="horizontal" />
<p class="type-surface-body-sm text-surface-muted">
A vertical one needs a height as well, which in a flex row is usually
<code>self-stretch</code>.
</p>
</div>
</div>
</template>
<script setup lang="ts">
import { Button, Separator } from '@maas/mirror/vue'
const actions = ['Edit', 'Duplicate', 'Share']
const button = [
'rounded-component-md border-surface border px-2.5 py-1',
'type-component-xs text-surface-muted hover:text-surface',
'transition-all duration-100 ease-linear',
'outline-4 outline-transparent focus-visible:focus-ring',
].join(' ')
const vertical = 'bg-surface-higher w-px self-stretch'
const horizontal = 'bg-surface-higher h-px w-full'
</script>
Usage guidelines
- Separator ships no CSS at all, so it is invisible until you give it a size and a colour. A one-pixel background on the axis it divides is the usual recipe.
- A vertical separator has no height in a flex row until it gets one, either
from
align-self: stretchor from an explicit size. - Use it where the division carries meaning. A line that is only decoration is
better off as a
borderon the element next to it, since that keeps it out of the accessibility tree.
Anatomy
Render it on its own.
| Name | Required | Description |
|---|---|---|
| Separator | true | Renders a <div role="separator">. |
<script setup lang="ts">
import { Separator } from '@maas/mirror/vue'
</script>
<template>
<Separator />
</template>
Examples
Horizontal and vertical
orientation decides what the separator divides, and is written to the element
as data-orientation, which is what you size it from.
<template>
<Separator class="separator" />
<Separator orientation="vertical" class="separator" />
</template>
<style>
.separator {
background: var(--app-color-surface-bg-higher);
}
.separator[data-orientation='horizontal'] {
block-size: 1px;
inline-size: 100%;
}
.separator[data-orientation='vertical'] {
align-self: stretch;
inline-size: 1px;
}
</style>
In a toolbar
Grouped actions read as groups once a separator sits between them, both on screen and out loud.
<template>
<div role="group" aria-label="Document">
<Button>Edit</Button>
<Button>Duplicate</Button>
<Separator orientation="vertical" class="separator" />
<Button>Delete</Button>
</div>
</template>
As another element
asChild hands the role and the data attribute to the element you render,
which is how a separator becomes an <hr> or a list item.
<template>
<Separator as-child>
<hr class="separator" />
</Separator>
<ul>
<li>Duplicate</li>
<Separator as-child>
<li role="separator" class="separator" />
</Separator>
<li>Delete</li>
</ul>
</template>
API reference
Standalone. Ordinary props, no store, no context. Separator takes no part
in a Field.
Separator
Renders a <div role="separator">.
Props
Emits
None. Separator has no state to report.
Slot props
Data attributes
CSS variables
None. A separator has no functional CSS, so its whole appearance is yours.
Errors
None. Separator has no context and no required prop.
Accessibility
The rendered element is a role="separator" that never takes focus, so it
carries no keyboard interaction.
A horizontal separator is the default in ARIA, so aria-orientation is only
written when the separator is vertical. Screen readers announce the division
either way.
A role="separator" that takes focus is a splitter. Separator never takes
focus, so build a splitter yourself where you need one.