DEV Community

Cover image for Building Scroll-Triggered Animations in Tailwind CSS Without External Libraries
HexShift
HexShift

Posted on

1

Building Scroll-Triggered Animations in Tailwind CSS Without External Libraries

Scroll-based animations usually mean reaching for heavy libraries like GSAP or ScrollMagic. But with Tailwind CSS and the native IntersectionObserver API, you can create highly performant, elegant scroll-triggered animations — zero extra libraries required. Let's build a full setup.

Why Native Scroll Animations?

Benefits of ditching the big libraries:

  • Smaller bundle size, faster load times
  • Full control over when and how elements animate
  • Progressive enhancement for older browsers

Step 1: Build a Tailwind Animation Class

First, extend Tailwind with a custom fade/slide animation:

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      keyframes: {
        fadeSlide: {
          '0%': { opacity: 0, transform: 'translateY(20px)' },
          '100%': { opacity: 1, transform: 'translateY(0)' },
        },
      },
      animation: {
        fadeSlide: 'fadeSlide 0.8s ease-out forwards',
      },
    },
  },
}

Step 2: Setup HTML Markup

Mark elements you want to animate with a hidden state:

<div class="opacity-0 translate-y-5 transition-all duration-700" data-animate>
  <h2 class="text-3xl font-bold">Reveal on Scroll</h2>
  <p>This section will fade and slide into view.</p>
</div>

Initially, the item is invisible and shifted slightly down.

Step 3: Use IntersectionObserver to Trigger Animation

Here's the vanilla JS magic:

<script>
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      entry.target.classList.remove('opacity-0', 'translate-y-5');
      entry.target.classList.add('animate-fadeSlide');
      observer.unobserve(entry.target);
    }
  });
}, {
  threshold: 0.2,
});

document.querySelectorAll('[data-animate]').forEach(el => observer.observe(el));
</script>

Each element with data-animate will animate the first time it comes into view. Then we unobserve to avoid retriggering.

Pros and Cons

✅ Pros

  • Zero dependencies — full native performance
  • Highly customizable with Tailwind’s animation system
  • Accessibility-friendly (no reliance on JavaScript for critical content)

⚠️ Cons

  • Requires small JS snippet per page (can't be pure CSS-only)
  • Some older browsers (like IE11) don't support IntersectionObserver (polyfills needed if critical)

🚀 Alternatives

  • Framer Motion + React: For app-level React animation control
  • Locomotive Scroll: If you want smooth scroll + parallax bundled together

Summary

Scroll-triggered animations don't need to bloat your app. With a pinch of Tailwind CSS and IntersectionObserver, you can deliver buttery-smooth, accessible motion experiences with minimal code — keeping your UI dynamic and your performance sharp.

If you found this useful, you can support me here: buymeacoffee.com/hexshift

JavaScript tools that help you ship faster

JavaScript tools that help you ship faster

Skip boilerplate and focus on features. Kinde handles auth, access control, and billing behind the scenes.

Get a free account

Top comments (0)

Tiger Data image

🐯 🚀 Timescale is now TigerData: Building the Modern PostgreSQL for the Analytical and Agentic Era

We’ve quietly evolved from a time-series database into the modern PostgreSQL for today’s and tomorrow’s computing, built for performance, scale, and the agentic future.

So we’re changing our name: from Timescale to TigerData. Not to change who we are, but to reflect who we’ve become. TigerData is bold, fast, and built to power the next era of software.

Read more

👋 Kindness is contagious

Explore this practical breakdown on DEV’s open platform, where developers from every background come together to push boundaries. No matter your experience, your viewpoint enriches the conversation.

Dropping a simple “thank you” or question in the comments goes a long way in supporting authors—your feedback helps ideas evolve.

At DEV, shared discovery drives progress and builds lasting bonds. If this post resonated, a quick nod of appreciation can make all the difference.

Okay