React Separator Component Examples
Copy-paste React Separator examples: horizontal between paragraphs, vertical inside a flex row, styled with custom colour, in a panel, and grouped sections.
Two blocks of content that belong to the same page but not to the same thought need a visible line between them — paragraphs in an article, groups of fields in a form, sections in a navigation rail. Drawing that line is the entire job of the Separator component in Drivn. The file at @/components/ui/separator.tsx imports react and the local cn() utility, keeps two class strings in a styles object, and returns one <div role="separator">. No state, no hook, no ref, and no dependency past the merge helper.
Every snippet below imports from @/components/ui/separator — the path the Drivn CLI writes the component to — and reaches for at most two props: orientation, which is 'horizontal' | 'vertical' and defaults to 'horizontal', and className for margin, colour, or thickness. The code is TypeScript throughout, because Drivn ships .tsx source and nothing else. Nothing in the file is client-only, so it carries no 'use client' directive and drops into a server component or a layout file without opening a hydration boundary.
What follows: a rule between two paragraphs, a vertical divider in a flex meta strip, colour and thickness overrides, a panel split from its action row, grouped sidebar sections, and the component source verbatim. Props are documented on the Separator docs page; the Radix-backed alternative is covered on Drivn vs shadcn Separator.
A horizontal divider between two paragraphs
The simplest use of a Separator is to drop one between two blocks of content to give them a visible break. The default orientation is 'horizontal', so no prop is needed — the component renders w-full h-px bg-border, which fills the available width and uses the bg-border token so the rule colour follows the theme along with every other border in the project.
Pass className="my-6" (or any margin utility) to add breathing room above and below. Without margin the divider sits flush against its siblings, which is what you want inside a tight list but rarely what you want between paragraphs. The example below pairs the divider with two <p> elements and adds vertical spacing through className — exactly the shape the Separator docs preview uses for the horizontal case.
1 import { Separator } from "@/components/ui/separator" 2 3 export default function Article() { 4 return ( 5 <article> 6 <p>The opening paragraph sets the scene.</p> 7 <Separator className="my-6" /> 8 <p>The next paragraph picks up after the break.</p> 9 </article> 10 ) 11 }
A vertical divider inside a flex row
Pass orientation="vertical" to switch to the vertical rule. The component swaps from w-full h-px bg-border to h-full w-px bg-border, so it now stretches to the height of its parent. That means a vertical Separator needs a sized container — a flex row with a fixed height, a toolbar, a header — or it collapses to zero height because there is no intrinsic content to measure.
The example below is the metadata strip you see under a blog post: author, separator, date, separator, reading time. The wrapper is a flex row with items-center and a h-6 height so the dividers have something to stretch into. The mx-3 on each Separator adds a touch of horizontal breathing room. For a stack of links separated by a slash or chevron rather than a rule, the Breadcrumb component handles the role with built-in spacing.
1 import { Separator } from "@/components/ui/separator" 2 3 export default function PostMeta() { 4 return ( 5 <div className="flex items-center h-6 text-sm text-muted-foreground"> 6 <span>Drivn</span> 7 <Separator orientation="vertical" className="mx-3" /> 8 <span>May 23, 2026</span> 9 <Separator orientation="vertical" className="mx-3" /> 10 <span>4 min read</span> 11 </div> 12 ) 13 }
A styled Separator with custom colour and thickness
One pixel, the bg-border token, full width — the defaults are deliberately quiet, because most dividers should be. When a break needs to read louder, className is the whole escape hatch. cn() merges what you pass over the class pulled from the styles object with later-class precedence, so h-0.5 beats h-px and bg-primary beats bg-border with no variant API sitting in between.
That leaves three knobs. Thickness: h-0.5 or h-1 on a horizontal rule, w-0.5 on a vertical one. Colour: any bg-* utility, including a token at partial opacity — bg-muted-foreground/20 is the muted text colour at twenty percent, which reads as a hairline that recedes into the page rather than cutting it. Spacing: the margin utilities, since the component ships none of its own. The example below stacks the default rule, a thicker primary-coloured one, and a faded one so all three are visible together.
For a divider with a word in the middle — the "OR" between an email form and an OAuth Button — the Separator still does the work. Put the label in a flex row between two Separators, give each flex-1, and the rules split the remaining width evenly on either side.
1 import { Separator } from "@/components/ui/separator" 2 3 export default function DividerStyles() { 4 return ( 5 <div className="space-y-6"> 6 <Separator /> 7 <Separator className="h-0.5 bg-primary" /> 8 <Separator className="bg-muted-foreground/20" /> 9 </div> 10 ) 11 }
The verbatim component source
Every detail above maps back to the same eight-line component file. The styles object holds the two orientation rules, the function reads the orientation prop, merges the matching class with whatever className you passed, and renders a div with role="separator". No state, no refs, no hooks, no Radix package. The full source is reproduced below from packages/drivn/src/registry/components/separator.ts so the entire component is visible at once.
That brevity is the reason a Separator can sit in any context — server component, client component, layout, marketing page — without making decisions about hydration or bundle weight on your behalf. After the Drivn CLI writes the file into your project, it is yours: rename it, change the role, drop the className prop, add a decorative flag of your own. The starting point is small enough that any of those edits is a one-line change.
1 import * as React from 'react' 2 import { cn } from '@/utils/cn' 3 4 const styles = { 5 horizontal: 'w-full h-px bg-border', 6 vertical: 'h-full w-px bg-border', 7 } 8 9 interface SeparatorProps { 10 orientation?: 'horizontal' | 'vertical' 11 className?: string 12 } 13 14 export function Separator({ 15 orientation = 'horizontal', 16 className, 17 }: SeparatorProps) { 18 return ( 19 <div 20 role="separator" 21 className={cn(styles[orientation], className)} 22 /> 23 ) 24 }
Install Drivn in one command
Copy the source into your project and own every line. Zero runtime dependencies, pure React + Tailwind.
npx drivn@latest createRequires Node 18+. Works with npm, pnpm, and yarn.
Frequently asked questions
The default orientation is horizontal, which renders w-full h-px bg-border — a one-pixel-tall rule that stretches the full width of its parent. Passing orientation="vertical" swaps in h-full w-px bg-border, a one-pixel-wide rule that stretches the full height of its parent. The vertical version needs a sized parent (a flex row with a height, for example) or it collapses to zero.
No. The Separator has no 'use client' directive, no hooks, and no event handlers. It is a plain function that returns a single div. You can render it directly inside server components, layout files, and statically rendered marketing pages without crossing a client boundary or adding to the JavaScript bundle for that route.
Yes. The default thickness is one pixel — h-px on a horizontal rule, w-px on a vertical one. Pass a className with a different size utility (h-0.5, h-1, w-0.5) and cn() will merge it with the defaults using later-class precedence, so the className wins. The same applies to colour, opacity, and margin utilities.
The Separator renders role="separator", which is the ARIA role for a thematic break between content. Assistive technology announces it as a divider rather than skipping it or reading it as content. If you want a purely visual rule that should be ignored, open the component file and either remove the role attribute or change it to role="none".