Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Text

Pro

Breathing Text for React

Text that breathes, the whole line slowly shrinking a touch and fading, then filling back. For React with Base UI, when a calm screen or a gentle wait should feel alive.

Framework

Breathing Text breathes a line in and out: the whole of it slowly shrinks a touch and fades as it breathes out, then fills back to itself as it breathes in, calm and steady, over and over. It can also soften a little on the way out, like breath on glass.

Use it for a meditation or wellness screen, a quiet hero, or a gentle waiting state ("Settling in…"). For letters that each move on their own, use Drift Text; for light running through the text, Shimmering Text. The text moves as one piece, never split into letters: one CSS keyframe animation the install adds to your stylesheet, from the text's own size and colour and back, so it never jumps when it starts or stops. There's no animation library. With reduced motion the text holds still.

Preview width

Breathe in, breathe out

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Usage

import { BreathingText } from "@/components/ui/breathing-text";
<h1>
  <BreathingText text="Breathe in, breathe out" />
</h1>

Demos

Intensity

intensity is how far the text shrinks and fades as it breathes out: subtle to 90% opacity, medium, the default, to 80%, strong to 70%. duration is one breath, out and in, 4000 ms by default; around six seconds matches a slow, calm breath.

Preview width

Blur

blur softens the text a little as it breathes out and sharpens it as it breathes in, for a dreamier breath. The softness scales with the text, so it shows best at a headline's size.

Preview width

Accessibility

The text stays real text, read by screen readers and selectable, since it's never split. At the end of a breath out it's at most 30% fainter (strong), so check that your text colour still contrasts with the page at that point: the default text colour does at every intensity. With reduced motion it holds still at its full size and colour.

FAQ

Why is breathing out longer than breathing in?

As in a calm breath: the text breathes out over a little more than half the cycle and in over the rest, eased like a slow sine, so it never feels mechanical.

Does the fading cost contrast?

Some: the text is up to 10%, 20% or 30% fainter at the end of a breath out, by intensity. Use it on text with good contrast to begin with, such as the theme's foreground, and keep a muted colour for subtle.

Does the text push the page around as it breathes?

No. It shrinks with a transform, which never changes the layout, and only to its own size, so it never overlaps the text around it.

How is it different from Drift Text?

Breathing Text moves the whole line as one, in one slow rhythm. Drift Text moves each letter on its own, so nothing lines up.

Can I use it for a waiting state?

Yes. Put it in an element with role="status", such as <p role="status"><BreathingText text="Settling in…" /></p>, so screen readers announce it when it appears.

What happens with reduced motion?

The text holds still at its full size and colour.

API Reference

BreathingText

<span> data-slot="breathing-text"

PropType
textstring

The text. Its line breaks (\n) are kept.

blur?boolean

The text also softens a little as it breathes out. @default false.

Default
false
duration?number

One breath, out and in, in milliseconds. @default 4000.

intensity?"subtle" | "medium" | "strong"

How far the text shrinks and fades as it breathes out. Every step keeps it readable; strong costs the most contrast.

Type
"subtle" | "medium" | "strong"
Default
"medium"
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Forwarded to the part.

CSS variableType
--breathing-text-blurstring

How soft the text gets with blur (0.04em).

--breathing-text-dimstring

How much it fades as it breathes out (0.2).

--breathing-text-durationstring

One breath, out and in (4s).

--breathing-text-shrinkstring

How much it shrinks as it breathes out (0.03).

All 97 text effects