ScrollReveal Hero Text Reset — reset: true Replay Explained

ScrollReveal Hero Text Reset · Heroes · Plain HTML, CSS & JS · Live preview

CategoryHeroes

What's included

Features

Explicit reset: true
The hero replays its entrance every time it re-enters the viewport, not just on first load.
Instant, invisible reset-out
Leaving the viewport snaps the hero back to its hidden state with no animated transition, avoiding a jarring reverse-play.
Hand-tuned sequencing
Four separate reveal() calls with explicit delays produce announcement-style pacing instead of a mechanical cascade.
Persistent IntersectionObserver
Unlike reset: false, the observer for each element is never torn down after first reveal.
Gradient headline text
A background-clip: text gradient gives the heading visual weight beyond flat color.
Scroll-context spacers
Tall spacer sections above and below make the enter/exit/re-enter cycle demonstrable without extra content.
Independent element timing
Tag, heading, subtext, and CTAs each animate on their own schedule rather than sharing one config.
Direct contrast with reset: false
Designed as a companion to this library's feature-grid snippet to show both reset behaviors side by side.

About this UI Snippet

ScrollReveal Hero Text Reset — What reset: true Actually Changes

Screenshot of the ScrollReveal Hero Text Reset snippet rendered live

Every other ScrollReveal snippet in this library sets reset: false (or relies on it as the default) because most content — a feature grid, a timeline, a pricing table — should reveal once and stay. A hero is the exception, and this snippet exists to make that exception explicit and to explain, precisely, what reset: true changes under the hood.

The default: reveal once, then disconnect

With reset: false, ScrollReveal attaches an IntersectionObserver to each target, and the first time that element crosses the visibility threshold, it plays the reveal animation and then calls unobserve() on it internally — the observer is torn down for that element. Scrolling it out of view and back in afterward does nothing, because nothing is watching it anymore. This is why the feature-grid and timeline snippets in this library never replay: it would be wasted motion for content the user has already read.

reset: true: the observer stays attached forever

With reset: true, ScrollReveal does not unobserve after the first reveal. Instead, on every subsequent IntersectionObserver callback, it checks direction: when the element's intersection ratio drops to zero (it has left the viewport), ScrollReveal reverses the animation — instantly resets the element back to its pre-reveal transform/opacity state, without an animated transition, so the hero looks "reset" rather than visibly un-animating. Then, the next time it crosses back into view, the full reveal transition plays again from that hidden state. The result: scroll past the hero, scroll back up, and the heading/subtext/CTAs all fade and slide in again exactly as they did on first load.

Why sequencing four separate reveal() calls instead of one

js sr.reveal('#shrTag', { delay: 0 ... }); sr.reveal('#shrTitle', { delay: 120 ... }); sr.reveal('#shrSub', { delay: 260 ... }); sr.reveal('#shrCtas', { delay: 400 ... });

Each hero element gets its own .reveal() call with an explicit, increasing delay rather than one call with interval across a shared selector. This is necessary because the four elements aren't visually interchangeable siblings (the way grid cards are) — they need specific, hand-tuned gaps (tag first, then a beat, then the headline, a longer beat before the CTAs) that read like an announcement rather than a mechanical cascade. interval assumes uniform spacing between same-type elements; explicit per-element delay is the right tool when the pacing itself is part of the design.

Reusing it

This is the pattern to reach for on any hero, landing page, or full-bleed intro section — anywhere a visitor might realistically scroll back to the top and would benefit from the entrance replaying rather than staying inert. Combine it with reset: false on everything below the fold, exactly as this library's two snippets demonstrate side by side.

Step by step

How to Use

  1. 1
    Add the ScrollReveal CDNInclude the scrollreveal UMD build from the CDN panel.
  2. 2
    Paste HTML, CSS, and JSA tall spacer sits above and below a centered hero section so scroll behavior is visible.
  3. 3
    Scroll down past the heroThe tag, heading, subtext, and CTAs reveal in sequence as the hero enters view.
  4. 4
    Keep scrolling, then scroll back upAs the hero leaves the viewport it resets instantly (no animation); re-entering plays the full sequence again.
  5. 5
    Compare with reset: falseSee the staggered-feature-grid snippet — same library, opposite reset choice, for content that should reveal once.
  6. 6
    Retune the pacingAdjust each element's delay to change how much of an "announcement" feel the sequence has.

Real-world uses

Common Use Cases

Landing page heroes
Replay the hero entrance every time it re-enters the viewport, using reset: true where most ScrollReveal content should reveal only once.
Product launch pages
Reward returning visitors with the entrance again, with four separate reveal() calls and explicit delays producing an announcement sequence.
Self-reintroducing name sections
Re-announce a name and tagline whenever the section is scrolled back to, snapping instantly to hidden when it leaves the view.
Single-page app top sections
Use for any hero a user can navigate back to, with a persistent observer per element watching for re-entry.
Presentation-style scrollytelling
Build sections meant to be rewatched, and use as a hands-on reference for the difference between reset: true and reset: false.

Got questions?

Frequently Asked Questions

With reset: false, ScrollReveal unobserves an element after its first reveal, so nothing fires when it leaves or re-enters the viewport afterward. With reset: true, the observer stays attached indefinitely: it fires again when the element's intersection ratio returns to zero (instantly reverting it to its hidden state, no transition) and again when it re-enters (replaying the full animated reveal).

ScrollReveal applies the hidden state instantly rather than transitioning back to it when an element with reset: true exits the viewport. If it animated the reverse too, you'd see the hero visibly un-animate every time you scrolled past it, which reads as broken rather than intentional — instant reset keeps only the entrance, not the exit, animated.

interval assumes a set of visually equivalent, same-type elements (like grid cards) that should stagger uniformly. A hero's tag, heading, subtext, and CTAs are different element types needing different, hand-picked gaps to feel like a deliberate announcement sequence rather than a mechanical list cascade — explicit per-call delay values give full control over that pacing.

Generally no — for a feature grid, timeline, or anything a user reads once and scrolls past, replaying the entrance every time they scroll back up over it feels repetitive rather than delightful. reset: true is best reserved for hero/intro sections a visitor might intentionally return to, such as by scrolling to the top or clicking a logo/anchor link.

Marginally — the observer for each element stays alive for the life of the page instead of being torn down after one reveal, so ScrollReveal keeps doing a small amount of bookkeeping on every intersection change. For a handful of hero elements this is negligible; it would be worth reconsidering only if reset: true were applied to hundreds of elements simultaneously.

Scroll down until the hero fully leaves the viewport (the bottom spacer's prompt confirms this), then scroll back up — the tag, heading, subtext, and CTAs will replay their entrance in the same 0/120/260/400ms sequence as on first load, since the observer never stopped watching them.

Build with AI

Build, Understand, Optimize, and Extend It With AI

This snippet's entire purpose is to make one configuration option's behavior tangible, so treat it as a debugging/understanding exercise. Paste it into an AI assistant like Claude and ask it to explain step by step what happens to the IntersectionObserver ScrollReveal creates internally as you scroll a reset: true element out of and back into the viewport, contrasted with what would happen if it were reset: false — walk through the unobserve call that never happens. Then ask why the exit reset is instant while the entrance is animated, and what UX problem an animated exit would cause. For extension, ask it to add a subtle blur-to-sharp transition alongside the existing translate/fade, make the CTA buttons get a small pop/bounce distinct from the text reveals, or build a small on-screen indicator that visibly logs each reveal/reset event as it fires, to make the observer's behavior fully visible rather than inferred.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a hero section that replays its entrance animation using ScrollReveal.js (v4, from a CDN) in plain HTML, CSS, and JavaScript.

Requirements:
- A tall spacer section above the hero and another below it (each roughly 70vh) with a short scroll-hint message, so the hero starts off-screen and the enter/exit/re-enter cycle is demonstrable.
- A centered hero section containing an eyebrow tag, a large two-line gradient-text heading, a subtext paragraph, and two CTA buttons (primary + ghost style).
- Construct the ScrollReveal instance with reset: true explicitly, and add a code comment explaining this is the opposite, deliberate choice from a typical content section (which would use reset: false) because a hero benefits from replaying its entrance whenever a visitor scrolls back to it.
- Reveal the tag, heading, subtext, and CTAs with FOUR SEPARATE reveal() calls (not one shared selector with an interval option), each with its own explicit increasing delay value (e.g. 0, 120, 260, 400ms) so the sequence reads as a hand-paced announcement rather than a uniform mechanical stagger.
- All four elements should animate a combination of opacity and a translate (origin/distance).
- Style it as a dark theme with a gold/amber accent color, a large gradient-clipped headline, and pill-shaped CTA buttons.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Source Code

Requires
<div class="shr-spacer">
  <p>↓ Scroll down to leave the hero, then scroll back up ↓</p>
</div>
<section class="shr-hero">
  <span class="shr-tag" id="shrTag">scrollreveal · reset: true</span>
  <h1 id="shrTitle">Ship faster.<br />Break less.</h1>
  <p id="shrSub">The deployment platform built for teams who move quickly without wanting to hold their breath.</p>
  <div class="shr-ctas" id="shrCtas">
    <button class="shr-btn shr-primary">Start Free</button>
    <button class="shr-btn shr-ghost">Watch Demo</button>
  </div>
</section>
<div class="shr-spacer">
  <p>↑ Scroll back up — the hero replays every time ↑</p>
</div>