scroll-text-reveal
v0.2.3
Published
A tiny GSAP-powered line reveal for text entering the viewport.
Downloads
641
Maintainers
Readme
scroll-text-reveal
A tiny TypeScript library that reveals text line by line when it enters the viewport. Built for static websites with GSAP, ScrollTrigger, and SplitText.
Features
- Line-by-line masked text reveal
- Flash-free initialization with the optional companion stylesheet
- One small function and seven practical options
- Configurable duration, trigger delay, line stagger, distance, start position, and easing
- Optional animation for elements visible during initialization
- Responsive line re-splitting after font loading and width changes
- Automatic screen-reader attributes through SplitText
- Automatic
prefers-reduced-motionsafeguard - Duplicate initialization protection
- ESM, CommonJS, and TypeScript declarations
Installation
pnpm add scroll-text-reveal gsapnpm install scroll-text-reveal gsapyarn add scroll-text-reveal gsapGSAP 3.13 or newer is required.
CDN
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/scroll-text-reveal/dist/styles.css"
>
<script type="module">
import scrollTextReveal from "https://cdn.jsdelivr.net/npm/scroll-text-reveal/+esm";
scrollTextReveal("[data-scroll-text-reveal]");
</script>The jsDelivr ESM endpoint resolves the required GSAP modules. The stylesheet is optional and prevents marked text from flashing before initialization.
Quick start
Add a selector to the text you want to reveal:
<h2 data-scroll-text-reveal>
A heading that reveals one line at a time.
</h2>Initialize it once after the page markup is available:
import { scrollTextReveal } from "scroll-text-reveal";
scrollTextReveal("[data-scroll-text-reveal]");Default and named imports are both supported:
import scrollTextReveal from "scroll-text-reveal";import { scrollTextReveal } from "scroll-text-reveal";The function accepts a CSS selector, one HTMLElement, or an iterable
collection of HTMLElements.
Preventing the initial text flash
The library works without CSS. However, the original text may briefly appear before JavaScript initializes the animation. To prevent this, import the optional stylesheet:
import "scroll-text-reveal/styles.css";
import { scrollTextReveal } from "scroll-text-reveal";It hides [data-scroll-text-reveal] elements until their animation is ready.
If JavaScript does not run, these elements remain hidden.
Configuration
scrollTextReveal(".reveal-heading", {
duration: 0.85,
delay: 0,
stagger: 0.1,
distance: 115,
start: 86,
ease: "power3.out",
animateInitiallyVisible: false,
});| Option | Type | Default | Description |
| --- | --- | --- | --- |
| duration | number | 0.85 | Animation duration in seconds |
| delay | number | 0 | Pause after the element reaches its viewport start position |
| stagger | number | 0.1 | Delay between consecutive lines in seconds |
| distance | number | 115 | Initial vertical offset as a percentage of each line |
| start | number | 86 | Viewport percentage at which the reveal starts |
| ease | string | power3.out | GSAP easing name |
| animateInitiallyVisible | boolean | false | Animate text already visible during initialization |
start: 86 means that the animation is triggered when the top of the element
reaches a point 86% down the viewport.
Delayed reveal
delay starts after ScrollTrigger activates the animation:
scrollTextReveal(".delayed-heading", {
delay: 0.5,
});Initially visible text
By default, text already visible when scrollTextReveal() runs is left
untouched. Enable its animation explicitly:
scrollTextReveal(".hero-heading", {
animateInitiallyVisible: true,
delay: 0.2,
});Direct elements
const heading = document.querySelector<HTMLElement>(".heading");
if (heading) {
scrollTextReveal(heading);
}scrollTextReveal(document.querySelectorAll<HTMLElement>(".reveal"));Calling scrollTextReveal() more than once for an element is safe. An element
that has already been initialized is ignored.
Accessibility
When a visitor requests reduced motion, the function returns before splitting or animating any text and removes the stylesheet's pending state.
SplitText uses aria: "auto" so the original text is exposed as a single
accessible label while generated lines are hidden from screen readers. For text
containing interactive nested elements such as links, review the alternative
accessibility strategy in the
SplitText documentation.
Browser support
The library targets modern browsers supported by GSAP and requires a browser
DOM. Call it after the relevant HTML has been parsed, either from a module at
the end of body or after DOMContentLoaded.
Development
pnpm install
pnpm typecheck
pnpm test
pnpm build
pnpm build:docsUse pnpm dev to open the demo.
