Se vuoi aggiungere animazioni allo scroll sul tuo sito, AOS (Animate On Scroll) è la scelta più rapida: zero dipendenze, CDN pronto, funziona con qualsiasi stack. In questa guida trovi tutti gli attributi, tutte le opzioni di configurazione globale e i bug più comuni con i fix relativi. Per la demo interattiva ufficiale visita michalsnik.github.io/aos.
Installazione
Via CDN (cdnjs)
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css" />
</head>
<body>
<!-- i tuoi contenuti -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js"></script>
<script>AOS.init();</script>
</body>Via npm (pacchetto ufficiale)
npm install aos
// nel tuo file JS
import AOS from 'aos';
import 'aos/dist/aos.css';
AOS.init();Tutti gli attributi data-aos
Ogni attributo si applica direttamente sull’elemento HTML. Sovrascrivono le impostazioni globali di AOS.init().
| Attributo | Valori / Default | Descrizione |
|---|---|---|
data-aos | vedi lista animazioni | Nome dell’animazione da applicare |
data-aos-duration | 400 (ms, range 50–3000) | Durata dell’animazione |
data-aos-delay | 0 (ms, range 0–3000) | Ritardo prima che l’animazione parta |
data-aos-offset | 120 (px) | Distanza dal bordo viewport per triggerare |
data-aos-easing | ease | Curva di accelerazione (vedi easing disponibili) |
data-aos-once | false | Se true, l’animazione avviene una sola volta |
data-aos-mirror | false | Se true, anima anche quando l’elemento esce dal viewport |
data-aos-anchor | — | Selettore CSS: usa un altro elemento come punto di trigger |
data-aos-anchor-placement | top-bottom | Punto dell’elemento / punto del viewport che triggerano l’animazione |
Valori data-aos-anchor-placement
Il formato è punto-elemento/punto-viewport. Esempi: top-bottom (default), top-center, top-top, center-bottom, center-center, bottom-bottom.
Easing disponibili
linear, ease, ease-in, ease-out, ease-in-out, ease-in-back, ease-out-back, ease-in-out-back, ease-in-sine, ease-out-sine, ease-in-out-sine, ease-in-quad, ease-out-quad, ease-in-out-quad, ease-in-cubic, ease-out-cubic, ease-in-out-cubic, ease-in-quart, ease-out-quart, ease-in-out-quart.
Lista completa delle animazioni
Fade
fade, fade-up, fade-down, fade-left, fade-right, fade-up-right, fade-up-left, fade-down-right, fade-down-left
Flip
flip-up, flip-down, flip-left, flip-right
Slide
slide-up, slide-down, slide-left, slide-right
Zoom
zoom-in, zoom-in-up, zoom-in-down, zoom-in-left, zoom-in-right, zoom-out, zoom-out-up, zoom-out-down, zoom-out-left, zoom-out-right
<div data-aos="fade-up" data-aos-duration="800" data-aos-delay="100">
Appare con fade verso l'alto, 800ms, ritardo 100ms
</div>
<div data-aos="zoom-in" data-aos-easing="ease-in-out-back" data-aos-once="true">
Zoom con bounce, si anima una volta sola
</div>
<div data-aos="flip-left" data-aos-anchor="#trigger" data-aos-anchor-placement="center-center">
Si anima quando #trigger è al centro del viewport
</div>AOS.init() — tutte le opzioni globali
Le opzioni di AOS.init() definiscono i default per tutti gli elementi. Ogni singolo elemento può sovrascriverle con i propri attributi data-aos-*.
AOS.init({
// Opzioni di base
offset: 120, // offset (px) dal bordo del viewport
delay: 0, // ritardo globale (ms), 0–3000
duration: 400, // durata globale (ms), 50–3000
easing: 'ease', // easing di default
// Comportamento
once: false, // true = anima solo al primo ingresso nel viewport
mirror: false, // true = anima anche all'uscita dal viewport
anchorPlacement: 'top-bottom', // punto trigger default
// Disabilita su certi dispositivi
disable: false, // false | 'phone' | 'tablet' | 'mobile' | funzione custom
});disable — disabilitare su mobile
Per disabilitare le animazioni su schermi piccoli (migliora performance e accessibilità):
AOS.init({
disable: function() {
return window.innerWidth < 768;
}
});Bug comuni e fix
Bug 1 — elementi invisibili al caricamento della pagina
Sintomo: alcuni elementi rimangono trasparenti e non si animano mai, soprattutto su mobile o con contenuto caricato dinamicamente.
Fix: chiama AOS.refreshHard() dopo che il DOM è completamente aggiornato.
// Dopo caricamento contenuto dinamico (es. fetch, lazy load)
AOS.refreshHard();
// Oppure al resize
window.addEventListener('resize', AOS.refresh);Bug 2 — animazione si triggerà troppo presto o troppo tardi
Sintomo: l’elemento si anima prima che l’utente lo veda, oppure solo quando è già metà pagina sopra il viewport.
Fix: aggiusta offset e anchorPlacement.
<!-- Si anima quando il top dell'elemento tocca il centro del viewport -->
<div data-aos="fade-up" data-aos-offset="0" data-aos-anchor-placement="top-center">
Contenuto
</div>Bug 3 — conflitti con overflow:hidden sul body
Sintomo: le animazioni slide (slide-left, slide-right) creano una scrollbar orizzontale temporanea.
Fix: aggiungi overflow-x: hidden al wrapper più esterno, non al body (altrimenti AOS non riesce a calcolare le posizioni correttamente).
/* NON fare questo */
body { overflow-x: hidden; }
/* FAI questo */
.page-wrapper { overflow-x: hidden; }Bug 4 — animazioni non funzionano con framework SPA (React, Vue, Next.js)
Sintomo: navigando tra le pagine di un’app SPA, AOS non si reinizializza e gli elementi rimangono invisibili.
Fix: reinizializza AOS ad ogni cambio di route.
// React — in un useEffect sul componente layout
import { useEffect } from 'react';
import AOS from 'aos';
useEffect(() => {
AOS.init({ duration: 600, once: true });
AOS.refresh();
}, [pathname]); // pathname da useLocation (React Router) o usePathname (Next.js)Bug 5 — iOS Safari: elementi che saltano o non si animano
Safari su iOS ha comportamenti particolari con le trasformazioni CSS durante lo scroll. Il fix più affidabile è disabilitare AOS su mobile e usare CSS puro per le animazioni di base, oppure impostare once: true per evitare ricalcoli continui.
AOS.init({
once: true, // evita ricalcoli allo scroll inverso
duration: 600,
disable: 'phone' // disabilita completamente su mobile se necessario
});Esempio completo copia-incolla
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AOS Demo</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css" />
<style>
.card { padding: 2rem; margin: 4rem auto; max-width: 600px; background: #f5f5f5; border-radius: 8px; }
</style>
</head>
<body>
<div class="card" data-aos="fade-up">Fade up — default</div>
<div class="card" data-aos="fade-right" data-aos-delay="100">Fade da sinistra con delay</div>
<div class="card" data-aos="zoom-in" data-aos-easing="ease-in-out-back">Zoom con bounce</div>
<div class="card" data-aos="flip-left" data-aos-once="true">Flip — solo una volta</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js"></script>
<script>
AOS.init({
duration: 700,
easing: 'ease-out',
once: false,
disable: function() { return window.innerWidth < 768; }
});
</script>
</body>
</html>Hai trovato utile questo articolo? Seguimi su @cyberalchimista per altri tutorial e consigli sullo sviluppo web. Per domande o progetti, contattami.

