Gli effetti di entrata e uscita sono animazioni che vengono attivate quando un elemento entra o esce dall'area visibile. Questo può essere utilizzato per creare esperienze utente coinvolgenti e dinamiche. Ad esempio, puoi utilizzare un effetto di entrata per applicare la dissolvenza in entrata a un elemento quando scorre nella visualizzazione o un effetto di uscita per ridurlo quando scorre fuori dalla visualizzazione.
Come implementare
Per aggiungere effetti di entrata e uscita a un elemento, devi combinare alcune proprietà CSS. Di seguito sono fornite istruzioni dettagliate:
Crea
@keyframesseparati per le animazioni di entrata e uscita. L'animazione di entrata verrà applicata quando l'elemento entra nell'area visibile, mentre l'animazione di uscita verrà applicata quando l'elemento esce.@keyframes slide-in { from { transform: translateX(-100%); } } @keyframes slide-out { to { transform: translateX(100%); } }Associa i fotogrammi chiave di entrata e di uscita all'elemento. Puoi farlo definendo più animazioni nella proprietà
animation.- Assegna all'animazione di entrata un valore
animation-fill-modedibackwardsin modo che applichi lo stato iniziale prima dell'inizio dell'animazione. - Assegna all'animazione di uscita un valore
animation-fill-modediforwardsin modo che mantenga lo stato finale al termine dell'animazione.
.animated-element { animation: slide-in 1s linear backwards, slide-out 1s linear forwards; }- Assegna all'animazione di entrata un valore
Crea una sequenza temporale di visualizzazione e collegala alle animazioni. Una View Timeline è un tipo di sequenza temporale collegata alla visibilità di un elemento nell'area visibile. Puoi crearne una utilizzando la funzione
view()e poi applicarla alle tue animazioni utilizzando la proprietàanimation-timeline..animated-element { animation-timeline: view(); }Per impostazione predefinita,
view()monitora l'elemento sull'asseblock. Se devi monitorarlo sull'asseinline, puoi utilizzareview(inline).Limita le animazioni agli intervalli
entryeexit. La proprietàanimation-rangeconsente di specificare in quale parte della sequenza temporale deve essere eseguita un'animazione.- L'intervallo
entrycopre il tempo che intercorre tra il momento in cui l'elemento entra per la prima volta nell'area visibile e quello in cui è completamente visibile. - L'intervallo
exitcopre il periodo di tempo che va dal momento in cui l'elemento inizia a uscire dall'area visibile fino a quando non viene completamente nascosto.
.animated-element { animation-range: entry, exit; }- L'intervallo
Esempio di codice
Questo codice anima i figli diretti dello scroller durante lo scorrimento utilizzando una cronologia di visualizzazione anonima:
@media (prefers-reduced-motion: no-preference) {
@supports ((animation-timeline: view()) and (animation-range: entry)) {
@keyframes grow {
from {
scale: 0.5;
}
}
@keyframes shrink {
to {
scale: 0.5;
}
}
.scroller > * {
animation:
grow auto linear backwards,
shrink auto linear forwards;
animation-timeline: view(inline);
animation-range: entry, exit;
}
}
}
Quando gli elementi entrano nello scrollport, viene riprodotta l'animazione grow, mentre quando escono dallo scrollport, viene riprodotta l'animazione shrink.
Il seguente codice ha lo stesso risultato visivo, ma anima gli elementi secondari diretti dello scroller durante lo scorrimento utilizzando una view-timeline con nome:
@media (prefers-reduced-motion: no-preference) {
@supports ((animation-timeline: view()) and (animation-range: entry)) {
@keyframes grow {
from {
scale: 0.5;
}
}
@keyframes shrink {
to {
scale: 0.5;
}
}
.scroller > * {
view-timeline: --tl inline;
animation:
grow auto linear backwards,
shrink auto linear forwards;
animation-timeline: --tl;
animation-range: entry, exit;
}
}
}
Best practice
Quando utilizzi le animazioni di scorrimento, è importante seguire alcune best practice per garantire un'esperienza fluida e accessibile:
- SÌ: includi il rilevamento delle funzionalità. Non tutti i browser supportano le animazioni basate sullo scorrimento. Utilizza
@supports ((animation-timeline: view()) and (animation-range: entry))per verificare il supporto e fornire un'alternativa per i browser che non lo supportano.- Il controllo
(animation-range: entry)DEVE essere incluso qui per filtrare i browser con supporto solo parziale. - NON utilizzare il pacchetto
scroll-timeline-polyfillper la strategia di riserva, in quanto non è completo di funzionalità e presenta molti problemi noti. - Se l'animazione è considerata solo decorativa, opta per il potenziamento progressivo e NON fornire un fallback.
- Il controllo
- SÌ: rispetta le preferenze degli utenti. Alcuni utenti preferiscono un movimento ridotto sul web. Utilizza la query supporti
prefers-reduced-motionper disattivare o ridurre le animazioni per questi utenti. - SÌ: prova ad animare solo le proprietà CSS con prestazioni elevate. Per ottenere animazioni più fluide, limita l'animazione alle proprietà che possono essere gestite dal thread del compositore del browser, come
transformeopacity. L'animazione di altre proprietà comewidthoheightpuò causare problemi di prestazioni. - SÌ: utilizza l'ordine di dichiarazione corretto. Quando utilizzi la proprietà abbreviata
animation, dichiaraanimation-timelinedopo per evitare che la proprietà abbreviata reimposti la sequenza temporale.
Quando utilizzi la funzione view() per creare un'animazione basata sullo scorrimento:
- FACOLTATIVO Specifica l'asse da monitorare: se non scegli come target l'asse
blockpredefinito (ad esempio in uno scroller orizzontale), specifica l'asse da monitorare conview(block)oview(inline). - Quando l'animazione non viene applicata al soggetto monitorato, utilizza una sequenza temporale di visualizzazione con nome.
Quando utilizzi la proprietà view-timeline per creare un'animazione basata sullo scorrimento:
- SÌ: utilizza un CSS
<dashed-ident>per il nome. - FACOLTATIVO Specifica l'asse da monitorare: se non scegli come target l'asse
blockpredefinito (ad esempio in uno scroller orizzontale), specifica l'asse da monitorare conview-timeline-axis. - SÌ: assicurati che l'ambito della ricerca funzioni. Quando l'elemento che dichiara
view-timelinenon è un antenato dell'albero piatto dell'elemento animato, aumenta la visibilità del nome diview-timelineutilizzandotimeline-scopesu un antenato condiviso.
Preferisci un view-timeline con nome quando è necessario animare più elementi o elementi secondari del soggetto monitorato.
Supporto del browser e strategie di riserva
Pertanto, in genere è necessaria una strategia di riserva.
Per i browser che non supportano le animazioni basate sullo scorrimento, puoi utilizzare un comportamento di riserva per ricreare gli effetti visivi. I fallback vengono in genere creati con un listener di scorrimento (per gli effetti ScrollTimeline) o con l'API IntersectionObserver (per gli effetti ViewTimeline).
Nei browser con supporto integrato per le animazioni basate sullo scorrimento, utilizza SEMPRE l'implementazione CSS nativa, in quanto è più efficiente.
Tieni presente che non tutti gli effetti possono essere ricreati utilizzando l'approccio dei fallback.
Per questo caso d'uso specifico, lo script seguente applica il comportamento di riserva per i browser che non supportano le animazioni basate sullo scorrimento. Utilizza un IntersectionObserver per monitorare la visibilità dell'elemento .wrapper e aggiorna la proprietà transform dei livelli in base alla posizione di scorrimento.
<script>
if (!CSS.supports('(animation-timeline: view()) and (animation-range: entry)')) {
const observer = new IntersectionObserver(
(entries) => {
for (const entry of entries) {
// This matches the effect as defined in the CSS example above.
// Customize this further if needed.
entry.target.style.scale = 0.5 + entry.intersectionRatio * 0.5;
}
},
{
threshold: Array.from({ length: 101 }, (_, i) => i / 100),
}
);
document.querySelectorAll('.scroller > *').forEach((el) => {
observer.observe(el);
});
}
</script>