In-view title
Bring a section title in as it scrolls into view.
textmotionheading
Preview
In-view title preview
Live · keyboard ready
When to use
- Section headings that should animate once they scroll into view.
- Feature pages where each section title needs a consistent entrance style.
- Headings that should replay on each entry, via once={false}.
When not to use
- Use text-reveal for hero copy that animates on load.
- Use scroll-highlight for a paragraph that follows scroll progress.
- Use text-shimmer for status lines, not headings.
shadcn CLI
Also installs (1)
- manicat-foundation
Manual install(+)
registry.jsonjson
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "in-view-title",
"type": "registry:ui",
"title": "In-view title",
"description": "Bring a section title in as it scrolls into view.",
"categories": [
"text"
],
"dependencies": [
"motion"
],
"registryDependencies": [
"https://manicat.viraza.net/r/manicat-foundation.json"
],
"files": [
{
"path": "registry/components/in-view-title/in-view-title.tsx",
"type": "registry:component",
"target": "@components/manicat/in-view-title/in-view-title.tsx"
},
{
"path": "registry/components/in-view-title/in-view-title.module.css",
"type": "registry:component",
"target": "@components/manicat/in-view-title/in-view-title.module.css"
}
],
"docs": "Docs and live preview: https://uiarc.dev/components/in-view-title",
"meta": {
"tier": "free",
"kind": "component",
"docs": "https://manicat.viraza.net/components/in-view-title",
"markdown": "https://uiarc.dev/components/in-view-title/markdown",
"tags": [
"text",
"motion",
"heading"
]
}
}Usage
Install the component, then copy this into your app. Change the content and the props to fit your screen.
example.tsxtsx
"use client";
import { InViewTitle } from "@/components/manicat/in-view-title/in-view-title";
export function InViewTitleExample() {
return (
<div className="w-full">
<InViewTitle
as="h2"
text="The heading in view, line by line."
lines={["The heading in view,", "line by line."]}
variant="line"
/>
</div>
);
}
Examples
Real screens rather than isolated props. Switch to Code to copy a whole example into your project.
Section title A heading that reveals line by line, with explicit line breaks.
Section title
A heading that reveals line by line, with explicit line breaks. preview
Live · keyboard ready
section-title-a-heading-that-reveals-line-by-line-with-explicit-line-breaks-.tsxtsx
"use client";
import { InViewTitle } from "@/components/manicat/in-view-title/in-view-title";
export function InViewTitleSectionExample() {
return (
<div className="w-full">
<InViewTitle as="h2" text="Designed in the open, shipped weekly." lines={["Designed in the open,", "shipped weekly."]} variant="line" />
</div>
);
}
Accessibility
- The heading carries aria-label with the full text; the animated parts are aria-hidden.
- Titles already scrolled past show immediately, and server-rendered titles appear on their own if scripts are slow.
- Choose as to match the page's heading outline.
Motion
- Triggers when 45% of the title is visible. Opacity leads, blur clears next, and the transform settles last, so text is readable before it fully arrives.
- Hiding (with once={false}) is a quick fade with no stagger.
- Reduced motion shows the title instantly with no transform, blur, or mask.
Responsive behavior
- Word, blur, and tracking variants wrap naturally at any width.
- The line variant uses your explicit lines, which do not rewrap, so keep each line short enough for mobile.
Performance
- One IntersectionObserver per title via useInView, triggering at 45% visibility.
- Each word or line is a motion span with blur and transform; fine for headings, not for long body text.
Notes for AI
- Default choice for section headings that should animate on scroll. Use text-reveal for on-load hero copy and scroll-highlight for a key paragraph.
- Pass lines only with variant="line"; the other variants split on words.