Skip to content
Textlab
1
Browse

ComponentsReveal

In-view title

Bring a section title in as it scrolls into view.

Make every word count

Installation

$ npx shadcn@latest add @textlab/in-view-title

Needs @textlab in your components.json. Setup takes a minute.

Usage

usage.tsx
import { InViewTitle } from "@/components/textlab/in-view-title/in-view-title";

<InViewTitle variant="words" text="Make every word count" />

Variants

blurwordslineswipe

Props

PropTypeDefaultDescription
text*string–The copy.
variant"blur" | "words" | "lines" | "wipe""blur"blur suits most headings; words and lines rise from a clip; wipe uncovers left to right.
as"h1" | "h2" | "h3" | "h4""h2"Heading level.
oncebooleantrueIn view: play once instead of on every entry.
amountnumber0.45Share of the title that must be visible before it starts.
delaynumber0Seconds before the first part moves.
reducedMotion"user" | "always" | "never""user"user follows the OS setting; always shows the still version.
classNamestring–Merged onto the root.
idstring–Forwarded to the heading, for anchor links.

When to use it

Reach for it

  • Section headings that should animate as the reader arrives.
  • Pages where every section title needs the same entrance.

Skip it

  • Hero copy that animates on load; use blur-reveal with trigger="mount".
  • A paragraph that follows scroll progress; use scroll-fill.

Accessibility and motion

Accessibility

  • Renders a real heading tag with the full text for screen readers.
  • Choose as to match the page outline.

Motion

  • Starts when 45% of the title is visible.
  • Titles already scrolled past show immediately.
  • Hiding with once={false} is a quick fade with no stagger.
Reduced motion. The title appears instantly with no blur, clip or mask.

Performance

  • One IntersectionObserver per title.
  • Fine for headings, not long body text.