Separator
A thin line that divides content — between sections of a page, groups in a menu, or items in a toolbar. It's a small primitive, but it handles the accessibility detail most hand-rolled dividers miss: whether the line is purely decorative or conveys real structure.
Usage
By default a separator is horizontal — a full-width line for dividing stacked content.
<script setup lang="ts">
import { Separator } from "@dlbcodes/ui";
</script>
<template>
<div class="w-full max-w-sm">
<div class="text-sm font-medium text-text-primary">Profile</div>
<div class="text-sm text-text-secondary">
Manage your public profile.
</div>
<Separator class="my-4" />
<div class="text-sm font-medium text-text-primary">Account</div>
<div class="text-sm text-text-secondary">
Update your account settings.
</div>
</div>
</template>
Vertical
Set orientation="vertical" to divide inline items, like entries in a toolbar or nav row.
<script setup lang="ts">
import { Separator } from "@dlbcodes/ui";
</script>
<template>
<!-- Vertical separators need a sized parent — here the row sets the height. -->
<div class="flex h-6 items-center gap-3 text-sm text-text-secondary">
<span>Docs</span>
<Separator orientation="vertical" />
<span>Components</span>
<Separator orientation="vertical" />
<span>Support</span>
</div>
</template>
A vertical separator takes its height from its parent, so it only shows when the container has a defined height — for example a flex row with a set height or items-stretch. Without that, there's nothing for the h-full line to fill.
In a card
A common use: separating a heading from the content below it, or fencing off a section within a panel.
<script setup lang="ts">
import { Separator, Button } from "@dlbcodes/ui";
</script>
<template>
<div
class="w-full max-w-sm rounded-2xl border border-border-subtle bg-bg-raised p-5"
>
<div class="font-medium text-text-primary">Workspace settings</div>
<div class="mt-1 text-sm text-text-secondary">
General preferences for this workspace.
</div>
<Separator class="my-4" />
<div class="flex items-center justify-between">
<span class="text-sm text-text-primary">Danger zone</span>
<Button variant="destructive" size="sm">Delete</Button>
</div>
</div>
</template>
Decorative vs. semantic
By default a separator is decorative (decorative is true) — it's hidden from assistive technology with role="none", because a purely visual divider is just noise to a screen reader.
If the separator marks a genuine structural break in content (not just visual polish), set :decorative="false". It then renders with role="separator" and the matching aria-orientation, so assistive tech announces the division.
When in doubt, leave it decorative — most dividers are visual.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | "horizontal" | "vertical" | "horizontal" | Direction of the line. Vertical needs a parent with a defined height. |
decorative | boolean | true | When true, hidden from assistive tech (role="none"). Set false for a semantically meaningful break (role="separator"). |
class | string | — | Classes merged onto the line — use for spacing (e.g. my-4) or color. |
Accessibility
- A decorative separator (the default) uses
role="none"so screen readers skip it — correct for dividers that are purely visual. - A semantic separator (
:decorative="false") usesrole="separator"witharia-orientation, announcing a real structural division. - The separator has no interactive behavior and isn't focusable.