Scroll Blur Focus — Free GSAP ScrollTrigger Snippet

Scroll Blur Focus · Scroll · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Animated blur
CSS blur() filter drives the focus.
Focus-in + out
Two scrubbed ranges meet at center.
Moving focal plane
Only the centered line is sharp.
Blur + opacity + scale
Three cues sell real focus.
Asymmetric easing
Snaps in, drifts out.
Scroll-ranged
Only near-center lines animate.
Reversible
Scrolling up re-focuses lines.
Works on any block
Text, images, or cards.

About this UI Snippet

Scroll Blur Focus — Lines That Snap Into Focus at Center

Screenshot of the Scroll Blur Focus snippet rendered live

Scroll blur focus is the editorial effect where each line of a statement is blurred and faint until it reaches the middle of the screen, where it snaps sharp and bright, then softens again as it scrolls away — a "depth of field that follows your reading" feel. This snippet builds it with GSAP and ScrollTrigger (from a CDN), using an animated CSS blur() filter.

Two scrubbed phases per line

Each line gets two ScrollTriggers. The first is a fromTo that animates from blur(8px), low opacity, and slightly scaled down to perfectly sharp as the line travels from top 75% up to center 45% — the focus-in. The second tween runs from center 45% to bottom 20%, blurring and dimming it again — the focus-out. Both are scrub: true, so the sharpness is a direct function of how close the line is to center; only the line crossing the focal zone is ever fully clear.

Why split into focus-in and focus-out

A single tween could fade a line in, but it couldn't also blur it back out symmetrically as it leaves. Splitting the lifecycle into two scrubbed ranges that meet at the focal point (center 45%) makes the line sharpen on approach and soften on departure, so the effect reads as a moving plane of focus rather than a one-way reveal. The handoff point is shared so there's no jump.

Filter, opacity, and scale together

Combining blur, opacity, and a subtle scale is what sells "focus": real lenses bring a subject up in clarity, brightness, and apparent size at once. Animating all three on the same scrub keeps them in lockstep. The easing differs per phase (power1.out in, power1.in out) so the snap into focus feels a touch quicker than the drift out.

A note on performance

Animated filter: blur() is heavier than transform/opacity because it's a real per-pixel blur, so the snippet keeps the blurred elements simple (single lines of text), uses will-change to promote them, and only animates the few lines near the viewport at any time. For long passages, limit how many lines blur at once — which this scroll-ranged approach does naturally, since off-screen lines aren't animating.

Reversible by construction

Because both phases are scrubbed, scrolling up runs them backward — a line that blurred out as you passed it sharpens again as you scroll back to it. There's no fixed timeline to get out of sync.

Customizing it

Change the blur amount, the focal position (center 45%), the scale, or the easing; apply it to images or cards instead of text. Pair it with a scroll text clip reveal, a text reveal scroll, or reveal on scroll.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You don't have to work out why the focal handoff feels seamless just by staring at the code. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why the two ScrollTriggers per line share the center 45 percent boundary, and what would visually break if the focus-in and focus-out ranges didn't meet at that exact point. The same assistant is useful for optimizing it — asking whether animating the blur filter on many long lines at once would tank frame rate, and whether narrowing the active scroll-trigger range per line would keep the cost bounded on longer passages. It's just as good for extending the effect: ask it to apply the same focus-in/focus-out pattern to images or cards instead of text, add a chromatic aberration accent alongside the blur, or make the focal point track the exact vertical center of the viewport dynamically rather than a fixed percentage. Treat the code less like a finished artifact and more like a starting point for a conversation.

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 "scroll blur focus" effect in plain HTML, CSS, and JavaScript using GSAP and its ScrollTrigger plugin (load both from a CDN, no build step).

Requirements:
- A vertical stack of text lines, each starting blurred via CSS filter: blur(8px), dimmed opacity, and slightly scaled down.
- For every line, create two separate ScrollTrigger-driven tweens, not one: a focus-in tween that animates from the blurred/dim/scaled-down state to fully sharp (blur(0px), opacity 1, scale 1) as the line travels from roughly the bottom quarter of the viewport up to the exact vertical center, and a focus-out tween that reverses the same properties as the line continues from that same center point up toward the top of the viewport.
- Both tweens per line must be scrub-linked to scroll position (scrub: true), not played on a timer, so the sharpness at any scroll position is a direct function of the line's distance from the viewport's center.
- The focus-in and focus-out tweens for a given line must share the exact same boundary position (e.g. "center 45%") so there is no visual jump or double-processing at the handoff point.
- Use different easing for the two phases (e.g. a quicker ease-out on the way in, a slower ease-in on the way out) so the snap into focus feels distinct from the drift away.
- Do not implement this with IntersectionObserver or manual scroll-position math — the blur amount must be driven purely by GSAP's scrub mapping of scroll position to each trigger's own start/end range.
- Add will-change hints on the animated properties and keep each animated block simple (single lines of text) since animating CSS filter: blur() is comparatively expensive.

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.

Step by step

How to Use

  1. 1
    Add the GSAP CDNsInclude gsap and ScrollTrigger from the CDN panel.
  2. 2
    Paste HTML, CSS, and JSBlurred lines of a statement render.
  3. 3
    Scroll downEach line sharpens as it reaches center.
  4. 4
    Keep scrollingLines blur again as they leave center.
  5. 5
    Scroll back upLines re-focus — both phases are scrubbed.
  6. 6
    Tune the focusChange the blur amount and focal point.

Real-world uses

Common Use Cases

Mission statements
Editorial
Focus lines like text reveal scroll.
Quotes
Sharpen a testimonial card line.
Section intros
Combine with reveal on scroll.
Storytelling
Galleries
Apply focus to a photo gallery.
Related: Scroll Card Fan
See the Scroll Card Fan for a related scroll pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

One handles focus-in and one handles focus-out. The first fromTo animates from blur, low opacity, and slight scale to sharp as the line moves from top 75% to center 45%; the second blurs and dims it again from center 45% to bottom 20%. Splitting the lifecycle lets a line sharpen on approach and soften on departure, so only the centered line is clear.

Real lenses bring a subject up in clarity, brightness, and apparent size together, so animating blur, opacity, and a subtle scale on the same scrub reproduces genuine focus rather than a flat fade. They move in lockstep, and slightly different easing per phase makes the snap into focus feel quicker than the drift out.

Animated filter: blur() is heavier than transform or opacity because it is a true per-pixel blur, so the snippet keeps blurred elements simple, promotes them with will-change, and only animates lines near the viewport at any moment. The scroll-ranged triggers mean off-screen lines are not animating, which keeps the cost bounded.

Yes. Both phases are scrub: true, so scrolling up runs them backward — a line that blurred out as you passed it sharpens again as you return to it. Because there is no fixed timeline, the focal plane simply follows the scrollbar in either direction with nothing to fall out of sync.

Render the lines, then in a mount effect register ScrollTrigger and loop the line refs to create the two scrubbed tweens each (use gsap.context or a scoped selector). Return a cleanup that reverts the context so triggers are removed on unmount. Keep will-change in CSS for smoothness; the markup and styles port unchanged.