Gli effetti di scorrimento del carosello sono un ottimo modo per aggiungere interesse visivo a un carosello. Mentre l'utente scorre le slide, ogni slide può essere animata quando entra, si centra ed esce dallo scrollport. Ad esempio, le slide possono apparire e scomparire gradualmente, ruotare o essere ridimensionate. In questo modo si crea un'esperienza utente dinamica e coinvolgente. A differenza delle semplici animazioni di entrata/uscita, questo effetto utilizza un'unica animazione continua per controllare l'aspetto della slide nell'intero scrollport.
Come implementare
Ecco come creare effetti di scorrimento del carosello:
Crea uno scroller: questo elemento fungerà da contenitore per le slide del carosello. In questo esempio viene utilizzato
overflow-x: scrollper consentire lo scorrimento orizzontale.<ul class="scroller"> <li class="entry">1</li> <li class="entry">2</li> <li class="entry">3</li> … </ul>.scroller { overflow-x: scroll; }Definisci l'animazione: crea un'animazione CSS che definisca i diversi stati delle slide mentre attraversano lo scrollport. Puoi definire i fotogrammi chiave per qualsiasi parte dell'animazione. Ad esempio, puoi definire uno stato per quando le slide si trovano al centro dello scrollport includendo un keyframe
50%. In questo esempio, la proprietàscalefa sì che le slide aumentino di dimensioni man mano che si avvicinano al centro e si rimpiccioliscano man mano che si allontanano.@keyframes animate { 0% { scale: 0.5; } 50% { scale: 1; } 100% { scale: 0.5; } }Applica l'animazione e
view-timeline: associa l'animazione alle slide del carosello e collegala a unview-timelineche monitora l'elemento mentre scorre nel container..scroller > * { animation: animate auto linear both; animation-timeline: view(inline); }Per impostazione predefinita,
view()monitora l'elemento sull'asseblock. Se devi monitorarlo sull'asseinline, puoi utilizzareview(inline).
Esempio di codice
Questo codice anima gli elementi del carosello di uno scroller orizzontale durante lo scorrimento utilizzando una cronologia di visualizzazione anonima:
@keyframes animate {
0% {
scale: 0.5;
}
50% {
scale: 1;
}
100% {
scale: 0.5;
}
}
.scroller > * {
/* Applies the animation using an `auto` duration */
animation: animate auto linear both;
/* Sets the animation timeline to use an anonymous view progress timeline, tracking the element's progress through the scroller on the inline axis */
animation-timeline: view(inline);
}
Questo codice anima gli elementi del carosello di uno scroller orizzontale durante lo scorrimento utilizzando una cronologia di visualizzazione con nome:
@keyframes animate {
0% {
scale: 0.5;
}
50% {
scale: 1;
}
100% {
scale: 0.5;
}
}
/* This creates a named view-timeline on each carousel item. The timeline is used to drive the animation that is applied on the same element. */
.scroller > * {
/* Applies the animation using an `auto` duration */
animation: animate auto linear both;
/* Defines a named view progress timeline, tracking the element's progress through the scroller on the inline axis */
view-timeline: --item inline;
/* Sets the animation timeline to use the named view progress timeline defined above */
animation-timeline: --item;
}
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-timelineeanimation-rangedopo per evitare che la proprietà abbreviata reimposti la sequenza temporale.
Preferisci un view-timeline con nome quando più elementi DOM devono essere animati in base alla stessa cronologia o quando devi animare gli elementi secondari dell'elemento su cui è definito view-timeline. Se l'elemento che animi è anche quello che definisce view-timeline, puoi utilizzare una sequenza temporale di visualizzazione anonima utilizzando view().
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 utilizzi la proprietà view-timeline per creare un'animazione basata sullo scorrimento:
- SÌ: utilizza un
<dashed-ident>CSS per il nome (ad es.view-timeline: --my-custom-name) - 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.
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 l'API Web Animations (Element.animate()) per creare un'animazione in pausa per ogni elemento del carosello. Poi, ascolta l'evento scroll sullo scroller e aggiorna il currentTime di ogni animazione in base all'avanzamento dello scorrimento dell'elemento all'interno dello scroller.
// Fallback for browsers that don't support scroll-driven animations
if (!CSS.supports('(animation-timeline: view()) and (animation-range: entry)')) {
const scroller = document.querySelector('.scroller');
const entries = document.querySelectorAll('.entry');
// Create a map to store animations
const animations = new Map();
entries.forEach(entry => {
const animation = entry.animate(
{
scale: ['0.5', '1', '0.5']
},
{
duration: 1, // We'll control the time ourselves
fill: 'both'
}
);
animation.pause();
animations.set(entry, animation);
});
// Update animations on scroll
const tick = () => {
const scrollerRect = scroller.getBoundingClientRect();
entries.forEach(entry => {
const animation = animations.get(entry);
if (!animation) return;
const entryRect = entry.getBoundingClientRect();
const progress = (entryRect.left + entryRect.width / 2 - scrollerRect.left) / scrollerRect.width;
animation.currentTime = progress;
});
};
scroller.addEventListener('scroll', tick);
tick();
}