Skip to content

Scroll Reveal Animations

Elements fade, slide, zoom or flip into view on scroll using IntersectionObserver and data-sr attributes, with stagger delays and reduced-motion support.

Live preview

Open in new tab

Code

Scroll reveal animations in pure CSS with a small vanilla JavaScript helper: headings, step cards, stats and a call-to-action fade, slide, zoom or flip into place as they enter the viewport. It is a lightweight alternative to animation libraries for landing pages, feature sections, timelines and portfolios.

How it works

Every element that should animate gets a data-sr attribute with an effect name: fade-up, fade-down, fade-left, fade-right, zoom or flip. The CSS defines the hidden start state for each effect (an opacity of 0 and a starting transform stored in --sr-from). Adding .sr-visible plays the sr-reveal keyframes from that transform to the resting position, using --sr-duration and the ease-out curve in --sr-easing, so the motion settles gently.

On DOMContentLoaded the script finds every .sr-root, reads data-sr-threshold and data-sr-repeat, and creates one IntersectionObserver per root. It copies each data-sr-delay value (in milliseconds) into the --sr-delay custom property, which the CSS uses as animation-delay to stagger neighbouring items. Only then does it add .sr-ready to the root and immediately reveals items that are already on screen. The hidden states are all scoped under .sr-ready, so if JavaScript fails or IntersectionObserver is missing, the content simply stays visible. Other items receive .sr-visible when they intersect; in the default one-shot mode the observer then stops watching it.

The demo section is a dark navy "workflow" layout: a header, four numbered .sr-step cards that slide in from alternating sides, three .sr-stat counters that zoom in, and a gradient .sr-cta panel that flips up.

Customization

  • data-sr="fade-up" on any element inside .sr-root: switch to fade-left, fade-right, fade-down, zoom or flip to change the entrance effect.
  • data-sr-delay="200": delays that element's animation by 200 ms; increase the value step by step to stagger a group.
  • data-sr-threshold="0.2" on .sr-root: how much of an element (0 to 1) must be visible before it animates.
  • data-sr-repeat="true" on .sr-root: elements hide again when they leave the viewport and replay every time they return.
  • --sr-distance in style.css: how far items travel (default 2.5rem); smaller values give a subtler effect.
  • --sr-duration and --sr-easing: the speed and curve of every reveal (default 0.8s).
  • --sr-accent and --sr-accent-2: the amber-to-coral gradient on the step numbers, stat values and the call-to-action panel.

Accessibility

The section is labelled by its heading with aria-labelledby, and the steps are an ordered list. The decorative step numbers are aria-hidden because the list already conveys order. Content is in the DOM from the start, so screen readers read it regardless of animation state. When the user has prefers-reduced-motion: reduce, the script does not hide anything and the CSS also forces every item to be visible with no animation. The call-to-action link has a clear :focus-visible outline.

Usage notes

You can place several .sr-root wrappers on one page; each has its own observer and settings. Avoid putting data-sr on elements that contain focusable controls you expect users to tab to before scrolling, or give them fade-up with a short distance.

Requirements

No dependencies. Pure HTML, CSS and JavaScript.

Scroll Reveal Animations – Pure CSS scroll animations component screenshot
Scroll Reveal Animations · Pure CSS Scroll Animations

More Scroll Animations

Reading Progress Bar – Tailwind CSS scroll animations preview

Reading Progress Bar

Sticky Tailwind CSS reading progress bar with a gradient fill, clickable chapter markers, current section label, minutes left and a circular back-to-top indicator.