Skip to content

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.

HorizontalDividing stacked sections.
<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.

VerticalDividing inline items.
<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.

In a cardSeparating sections 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 ​

PropTypeDefaultDescription
orientation"horizontal" | "vertical""horizontal"Direction of the line. Vertical needs a parent with a defined height.
decorativebooleantrueWhen true, hidden from assistive tech (role="none"). Set false for a semantically meaningful break (role="separator").
classstring—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") uses role="separator" with aria-orientation, announcing a real structural division.
  • The separator has no interactive behavior and isn't focusable.