Updated June 2026, guidance and the IntersectionObserver / reduced-motion code below apply to PrestaShop 8 and 9 (Hummingbird and Classic). Accessibility notes reflect the EU Accessibility Act now in force.
Scroll animations, elements that fade in, slide up, or zoom into place as the page scrolls past them. Sit in an awkward spot for a store owner. On a brand or homepage they make a shop feel considered and alive; on a product grid or in checkout they add a half-second of "where did my button go?" that costs you orders. The skill isn't knowing how to add them. It's knowing where on a PrestaShop store they earn their keep, where they quietly leak conversions, and how to add them without dragging your PageSpeed score down. This guide is specifically about that judgement call on a PrestaShop store, which templates, which back-office surfaces, and the performance budget you have to respect.
If your actual goal is getting custom front-end code to survive theme updates, that's a different (and important) problem, we cover it separately in custom CSS and JavaScript in PrestaShop without breaking updates. Here we assume you've decided you want movement and need to do it right.
Where scroll animations belong, and where they cost you orders
PrestaShop is a transactional platform, not a portfolio site. The honest rule: animate the pages where a visitor is browsing or being persuaded, never the pages where they're buying or comparing. Mapped onto the actual controllers and templates you'll be editing:
| PrestaShop surface | Controller / template | Animate? | Why |
|---|---|---|---|
| Homepage | IndexController / index.tpl | Yes, sparingly | The one page that tells a brand story; fade-in per section reads as polish, not delay. |
| CMS pages (About, brand, lookbook) | CmsController / cms.tpl | Yes | Editorial content; movement gives it an almost-cinematic feel without hurting a sale. |
| Category / product listing | CategoryController / catalog/listing/category.tpl, product-list.tpl (+ miniature partials) | No | Customers scan a grid. Animating cards as they enter the viewport turns scanning into waiting. |
| Product page | ProductController / product.tpl | No (price/cart/photos) | Price, add-to-cart and gallery must be instant. Delaying them is friction at the decision point. |
| Checkout | OrderController / checkout/*.tpl | Never | Every millisecond here is a potential lost order. Zero animation, full stop. |
So what does that mean for you? The temptation is to flip on a "fade everything" library theme-wide and admire it on your desktop. The store owner's job is the opposite: scope animation to homepage and CMS templates only, and explicitly exclude the templates where customers are deciding and paying. A category grid that hesitates before showing products doesn't look premium, it looks broken on a slow connection.
The mobile reality check
Over half of most PrestaShop stores' traffic is on a phone, and that's exactly where scroll animation degrades. What's buttery on a MacBook is choppy on a three-year-old Android. Test on real mid-range hardware, not your dev machine, and treat mobile as a reason to do less, not a place to show off. PrestaShop's responsive themes already reflow heavily on small screens; layering animation on top of that reflow is where janky scrolling comes from.
Animation types that suit an e-commerce store
- Fade in. Opacity 0 → 1. The safest effect, appropriate for any content block. If you only pick one, pick this.
- Slide up. The element rises 20–30px while fading in. A touch of depth; good for testimonial or feature cards on the homepage.
- Staggered reveal. Each item in a row animates a beat after the last, creating a cascade. Reserve it for a curated homepage block, a hand-picked "featured" row, never the category grid, where it just slows scanning.
- Parallax. Background moving at a different speed than foreground. It can look striking on a single hero or brand-story section, but it's performance-heavy and a frequent source of mobile jank. One section per page, maximum, and test it on a phone before you ship it.
The design rules that keep it subtle
The difference between "premium" and "annoying" is entirely in the settings, not the technique:
- Subtlety. If a visitor consciously notices the animation, it's too much. Elements should feel like they naturally appeared, not performed.
- Speed. 200–400ms is the sweet spot. Faster feels snappy; slower feels laggy. Never exceed 600ms. No one should wait for your page to finish moving before they can read it.
- Once only. Animate an element the first time it enters the viewport, then leave it alone. Re-animating every time the customer scrolls back up is the single most common way to make a nice effect feel cheap.
- Respect motion preferences. Some visitors set
prefers-reduced-motionat the OS level (often for vestibular disorders). Honour it, and note that the EU's accessibility rules expect your store to stay fully usable for people who do.
Performance and accessibility: the non-negotiables
This is where most DIY scroll-animation attempts hurt a PrestaShop store rather than help it. Two technical realities decide whether your animation is free or expensive:
Only animate opacity and transform. These two properties are handled on the browser's compositor, they don't force the page to recalculate layout, so the main thread stays free for everything else. Animating width, height, top, left, margin or padding triggers a layout reflow on every frame, and on a content-heavy PrestaShop category page that's exactly the kind of cost that shows up as a stutter.
Use the Intersection Observer, never scroll-event listeners. A naïve window.addEventListener('scroll', ...) fires dozens of times a second and competes with PrestaShop's own front-end scripts (the cart, the faceted-search ajax, the carousel). The Intersection Observer fires only when an element actually crosses into view, which is both correct and cheap.
On accessibility, the floor is: never hide essential content behind an animation that depends on JavaScript, if a script fails, the content (and especially the price and the buy button) must still be there. Don't animate text while a screen reader may be reading it, and avoid any flashing or rapid movement. The European Accessibility Act treats animations that block or hinder access to content as a compliance problem, not a stylistic one.
The two CSS rules that do the heavy lifting
A correct, lightweight fade-in is mostly CSS. The JavaScript only adds one class when the element enters view. The pattern below animates only opacity and transform, and it includes the prefers-reduced-motion guard that keeps you on the right side of accessibility. This is vanilla CSS, no library:
/* hidden state: paint it, but offset and transparent */
.mpr-reveal {
opacity: 0;
transform: translateY(24px);
transition: opacity .35s ease, transform .35s ease;
}
/* JS adds .is-visible when the element scrolls into view */
.mpr-reveal.is-visible {
opacity: 1;
transform: translateY(0);
}
/* respect the visitor's OS-level motion preference */
@media (prefers-reduced-motion: reduce) {
.mpr-reveal {
opacity: 1;
transform: none;
transition: none;
}
}
And the observer that toggles the class once, then stops watching the element. Note the unobserve call, which is how you honour the "animate once only" rule without leaving listeners running:
const io = new IntersectionObserver((entries, obs) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add('is-visible');
obs.unobserve(entry.target);
}
});
}, { threshold: 0.15 });
document.querySelectorAll('.mpr-reveal').forEach((el) => io.observe(el));
Ship that JS as an external file registered through your module's asset hook, not as an inline <script> in a template, for the reasons covered in the custom-CSS/JS guide above. Scope the .mpr-reveal class to homepage and CMS templates only, exactly as the table maps it.
Three ways to add scroll animations to PrestaShop
| Route | Effort | Survives theme update? | Best when… |
|---|---|---|---|
| Hand-code into a child theme | Developer time | Protected, but review after parent/core updates | You have a developer and want total control. Never edit the parent theme directly. |
| A lightweight library (e.g. AOS) | Low. Add the script, tag elements with data-aos | Depends, re-applied after every theme change | You're comfortable touching template files and want a quick win. |
| A back-office module | Install & configure, no code | Yes, independent of the theme | You want per-element control without a developer or template edits. |
The first route deserves one warning that trips up most merchants: if you're editing theme files to add the script and CSS, do it in a child theme, or your next theme update will silently wipe the lot. We explain exactly why and how in child themes in PrestaShop: why you should never edit the parent theme. And avoid the heavyweights. Full frameworks like GSAP or Anime.js add 30–60KB of JavaScript for capabilities a store will never use; a basic fade-and-slide does not justify that weight on a checkout-funnel site.
One related micro-interaction worth scoping in at the same time, since it's the same Intersection-Observer family of work: a back to top button that fades in once the visitor scrolls past the fold. It's the rare bit of scroll-triggered movement that's welcome on every page, because it removes friction instead of adding it.
Where the Scroll Animations module fits

The Scroll Animations settings show an enable toggle, an animation-type dropdown, delay and duration fields, and a CSS selectors field.
The module route exists for the store owner who wants the homepage to feel considered but doesn't want to fork a theme or hand-write Intersection-Observer code that breaks at the next update. Our Scroll Animations module adds configurable fade, slide and zoom effects to any element from the back office, built on a native IntersectionObserver with no external dependencies, so it doesn't drag a 30KB framework onto your pages. So what does that buy you? You control duration, trigger point and effect per element from the admin instead of a developer invoice; the animation logic lives in the module, not your theme, so a theme update can't erase it; and because it leans on opacity and transform on the compositor, it's built to keep your PageSpeed score intact rather than spend it.
Whichever route you take, the discipline is the same and it's the part DIY guides skip: scope movement to the pages that persuade, keep it off the pages that sell and the pages that charge, animate only opacity and transform, and test it on a real phone before you call it done. A scroll animation should make a visitor feel the page is alive. Never make them wait for it to settle before they can buy.
Frequently asked questions
Where on a PrestaShop store is it safe to use scroll animations?
Animate the pages where a visitor is browsing or being persuaded, the homepage (sparingly) and CMS pages like About or a lookbook. Keep movement off category listings, product pages and checkout, where customers are scanning, deciding and paying. A category grid that hesitates before showing products reads as broken, not premium, and any delay at checkout directly risks the order.
Why does everyone insist on IntersectionObserver instead of a scroll listener?
A scroll event listener fires dozens of times a second and competes with PrestaShop's own front-end scripts, the cart, faceted-search ajax, the carousel. IntersectionObserver fires only when an element actually crosses into view, so it's both correct and cheap. It also makes the "animate once" rule trivial: call unobserve on the element after it's revealed and the browser stops watching it entirely.
Which CSS properties are safe to animate?
Only opacity and transform. Both are handled on the browser's compositor and don't force a layout recalculation, so the main thread stays free. Animating width, height, top, left, margin or padding triggers a reflow on every frame, and on a content-heavy category page that's exactly the cost that shows up as a stutter.
Do I have to support prefers-reduced-motion?
Yes, and it's one media query, shown in the snippet above. Some visitors set prefers-reduced-motion: reduce at the OS level, often for vestibular disorders. Honouring it isn't just courtesy: the EU Accessibility Act treats animations that hinder access to content as a compliance problem. Inside that media query, set the element to its visible state with no transition so it appears instantly.
Is a library like AOS or GSAP a good idea?
AOS is a reasonable quick win if you're comfortable tagging elements with data-aos in a child theme. Avoid the heavyweights. GSAP and Anime.js add 30–60KB of JavaScript for capabilities a store will never use, and a basic fade-and-slide doesn't justify that weight on a checkout-funnel site. The vanilla IntersectionObserver pattern above is a few lines and carries no framework cost at all.
Will scroll animations hurt my PageSpeed score?
They don't have to. Done right, animating only opacity and transform, using IntersectionObserver, scoping the effect to a couple of templates, and skipping heavy frameworks. The cost is negligible. They start to hurt when you flip on a "fade everything" library theme-wide, animate layout-triggering properties, or load a 30KB animation framework for a single fade. Scope tightly and test on a real mid-range phone.
Why does my animation feel janky on phones but smooth on my laptop?
Because over half your traffic is on mobile and that's where the animation degrades. A three-year-old Android has far less headroom than your dev machine, and PrestaShop's responsive themes already reflow heavily on small screens. Layering animation on top of that reflow is where the jank comes from. Treat mobile as a reason to do less: fewer animated elements, no parallax, and always verify on real mid-range hardware.
Comments
Leave a comment
Share a question, an installation detail, or feedback that could help another reader.