How to implement scroll-triggered text reveal animation from design mockup

I’m working on converting a design mockup into actual web code and need help with a specific animation effect. The goal is to create text that gets revealed or morphs as the user scrolls down the page. I’ve been struggling with getting the animation to work properly despite multiple attempts.

As someone who’s still learning web development, I’m not sure what approach would work best for this type of scroll-based text animation. Here’s what I’ve tried so far:

const overlayElement = document.querySelector('#overlay-div');
window.addEventListener('scroll', updateAnimation);

function updateAnimation() {
  const currentScroll = document.documentElement.scrollTop;
  const totalHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight;
  const percentage = `${(currentScroll / totalHeight) * 100}%`

  overlayElement.style.height = percentage;
}
body {
  height: 200vh;
  margin: 0;
}

#overlay-div {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 0;
  background-color: black;
}
<div id="overlay-div"></div>

The animation should create a smooth transition where text appears to morph or get uncovered as you scroll. What would be the most effective method to achieve this kind of scroll-triggered text reveal effect?

Honestly, just use transform: translateY() with a negative value that decreases as you scroll. Way simpler than messing with height changes. Put your text in a container with overflow: hidden and animate the text element inside moving up from below. Less janky than overlay divs and doesn’t need blend modes or anything fancy.

Your overlay div approach is solid, but there’s a scroll calculation issue that’s probably driving you nuts. You’re dividing by totalHeight (the full document height), but you want window.innerHeight as your denominator for smooth animations. I’ve built similar effects and found that adding transform: translate3d(0,0,0) to both text and overlay elements stops that annoying flicker during scroll. Also, throw requestAnimationFrame inside your scroll handler - it syncs with the browser’s refresh rate and makes everything buttery smooth. One trick that worked great for me: create two identical text elements - one visible, one hidden behind the overlay. As the overlay moves up, it reveals the hidden text underneath. Gives you way more control over styling and you can make the revealed text a different color or weight for better contrast.

Your scroll calculation needs work. Try window.innerHeight instead of clientHeight - it’s way more consistent across browsers. The overlay div approach is good, but you’ll want to debounce that scroll listener or it’ll lag on slower devices. Just wrap it in a setTimeout with like 10ms delay.

For the text morphing effect, use CSS mix-blend-mode on your overlay with contrasting colors. Set your text to white, overlay to black, then add mix-blend-mode: difference - that’ll give you the reveal effect as the overlay moves up. Throw will-change: height on the overlay CSS too for better rendering.

You’ve got the main part right though - overlay starting from bottom and moving up as you scroll down.

Your code looks good but you might have a positioning issue with the overlay. I ran into the same thing when I started with scroll animations - switching from position: absolute to position: fixed gave me way more predictable results. Try using Intersection Observer API with CSS transforms instead of calculating scroll percentages manually. It’s much smoother. Also, add transform: translateZ(0) to your animated elements - it enables hardware acceleration and boosts performance. For text reveals, CSS clip-path or mask properties work great. You can animate the clip-path based on scroll position to get that uncovering effect. Or use CSS custom properties that you update with JavaScript - keeps the animation in CSS while JS handles the scroll math.