- La moderna funzionalità CSS scroll-snap trasforma i semplici scroller in carousel fluidi e impaginati senza l'utilizzo di JavaScript.
- Nuovi pseudo-elementi come ::scroll-button() e ::scroll-marker() generano controlli carosello accessibili utilizzando solo CSS.
- Le strategie basate esclusivamente su CSS, abbinate a soluzioni di ripiego accurate e al supporto di ARIA, consentono di realizzare caroselli veloci, resilienti e inclusivi.
- JavaScript diventa facoltativo, riservato a casi limite come veri e propri cicli infiniti o comportamenti complessi con stato.
Creare caroselli utilizzando esclusivamente il CSS moderno non è più un'utopia.—è un'opzione molto reale e pronta per la produzione che spesso può superare le prestazioni delle classiche librerie di slider JavaScript. Grazie a funzionalità come Aggancio allo scorrimento, animazioni basate sullo scorrimento, pseudo-elementi carosello sperimentali e primitive di accessibilità robuste, puoi spedire caroselli leggeri e resistenti che risultano comunque fluidi, interattivi e rifiniti.
Se sei stanco di scaricare pacchetti JavaScript da 50 KB solo per mostrare alcune diapositive, questa guida ti illustra cosa può fare per te il CSS di oggi. Analizzeremo i concetti chiave alla base dei caroselli solo CSS, come collegarli con scroll-snap, quando affidarsi al nuovo ::scroll-button() e ::scroll-marker() pseudo-elementi e come inserire l'autoplay o comportamenti circolari, pur continuando a considerare l'accessibilità e le prestazioni come elementi prioritari.
Perché i caroselli realizzati esclusivamente con CSS sono finalmente un'opzione valida
Per anni, "carosello" è stato quasi sinonimo di "plugin JavaScript".Soluzioni come Swiper, Glide o slider sviluppati internamente erano l'approccio più diffuso: gestivano la navigazione, lo stato, il supporto da tastiera e i gesti touch, ma a costo di un peso aggiuntivo, di listener di eventi ovunque e di una discreta quantità di acrobazie del DOM.
Il CSS moderno ha colmato silenziosamente gran parte di questo divario.Con proprietà come scroll-snap-type e scroll-snap-align, puoi trasformare qualsiasi scroller orizzontale o verticale in un'esperienza paginata. Inoltre, la specifica CSS Overflow Level 5 introduce elementi generati dal browser pulsanti di scorrimento e indicatori che si comportano come un'interfaccia utente a carosello completa, ma sono dichiarate interamente in CSS.
Il grande vantaggio è che il browser, e non il tuo codice JavaScript, diventa responsabile delle problematiche principali relative all'esperienza utente.: fisica dello scorrimento, navigazione da tastiera, ordine di messa a fuoco e persino ruoli ARIA per i controlli del carosello. In molti casi è davvero difficile creare qualcosa di più accessibile e performante di ciò che la piattaforma offre di serie.
Un altro importante vantaggio dei caroselli CSS è la resilienza.Se JavaScript non si carica, gli utenti con gli script bloccati o disabilitati ottengono comunque un set di elementi scorrevoli perfettamente utilizzabile. Non c'è idratazione, non si verificano spostamenti del layout dovuti al caricamento ritardato del codice e ci sono molti meno elementi che possono causare problemi nel tempo.
Elemento costitutivo fondamentale: un contenitore scorrevole con Scroll Snap
Ogni carosello realizzato esclusivamente con CSS inizia la sua vita come un normale contenitore scorrevole.Immaginate un semplice elenco di diapositive che possono essere scorse orizzontalmente. A partire da queste, aggiungete la funzione di aggancio allo scorrimento in modo che la finestra di visualizzazione si blocchi automaticamente su ciascuna diapositiva.
La struttura HTML minimale per un carosello orizzontale è volutamente semplice.: un elemento wrapper e una serie di elementi slide al suo interno. Potresti usare un ul con li elementi, o un div con bambino divs—CSS si occupa del lavoro più gravoso, quindi non sono necessarie classi speciali per ogni bambino, a meno che il progetto non lo richieda.
Una configurazione base di scroll-snap potrebbe apparire così in CSS, ipotizzando una visualizzazione a larghezza intera e su una singola diapositiva:
.carousel { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth; }
.carousel-item { flex: 0 0 100%; scroll-snap-align: center; }
Qui il contenitore utilizza display: flex allineare i propri figli orizzontalmentee overflow-x: auto per abilitare lo scorrimento. La magia è in scroll-snap-type: x mandatory, che indica al browser che lo scorrimento orizzontale dovrebbe sempre fermarsi su un punto di aggancio valido, e in scroll-snap-align: center su ciascuna diapositiva, che definisce quei punti di aggancio.
Questa combinazione di flexbox e scroll snap dà immediatamente la sensazione di un carosello: gli utenti scorrono o trascinano e la diapositiva più vicina si posiziona automaticamente. Poiché sfrutta lo scorrimento nativo, l'input touch su telefoni e tablet funziona senza problemi, senza alcun gestori di gesti o biblioteche aggiuntive.
Non sei limitato a un solo articolo per visualizzazionePer i caroselli a più colonne che mostrano diverse schede contemporaneamente, è possibile utilizzare una larghezza flessibile per gli elementi, ad esempio:
.carousel-item { flex: 0 0 calc(33.333% - 1rem); margin: 0 0.5rem; scroll-snap-align: center; }
Questa variante consente di visualizzare, ad esempio, tre schede per viewport con un po' di spazio, pur continuando a beneficiare del comportamento di aggancio. Gli utenti scorrono pagine di schede anziché singole diapositive principali, il che funziona benissimo per elenchi di prodotti o gallerie.
Pulsanti di scorrimento con lo pseudo-elemento ::scroll-button()
Una volta ottenuto uno scroller a scatto, la cosa successiva che la maggior parte delle persone desidera sono dei pulsanti di navigazione espliciti.—controlli precedente e successivo che spostano il carosello a sinistra o a destra. Tradizionalmente, si creerebbe <button> elementi, associa eventi di clic e calcola di quanto scorrere.
La specifica CSS Overflow 5 introduce ::scroll-button(), uno pseudo-elemento che permette al browser di occuparsi di tutto il lavoro pesanteSebbene questa funzionalità sia attualmente disponibile a partire da Chrome 135 (e inizialmente solitamente tramite flag sperimentali), offre un'anteprima di come verranno creati i caroselli in futuro.
I pulsanti di scorrimento si dichiarano nello stesso modo in cui si dichiara qualsiasi altro pseudo-elementoAd esempio, per generare i pulsanti sinistro e destro per il tuo carosello:
.carousel::scroll-button(left) { content: "⬅" / "Scroll left"; }
.carousel::scroll-button(right) { content: "⮕" / "Scroll right"; }
.carousel::scroll-button(*) :focus-visible { outline-offset: 5px; }
Quando questo CSS viene applicato, il browser crea effettivamente elementi reali <button> elementi come fratelli del contenitore di scorrimentoLi collega allo scroller, assegna i ruoli appropriati e ne definisce il comportamento. Un singolo clic in genere scorre circa l'85% dell'area di scorrimento, che corrisponde a una "pagina" nella maggior parte dei layout a carosello.
Se il tuo progetto prevede esattamente un elemento a larghezza intera per clic, puoi combinare questi pseudo-elementi con uno snap più rigoroso su ogni figlio aggiungendo scroll-snap-stop: alwaysCiò costringe la finestra di visualizzazione ad atterrare sui bordi dell'elemento anziché fermarsi a metà.
La proprietà del contenuto qui svolge una doppia funzione: il primo valore è ciò che gli utenti vedono visivamente (in questo caso, caratteri freccia), e la seconda stringa è un testo di fallback accessibile che può essere esposto alle tecnologie assistive. È possibile personalizzare lo stile e il posizionamento di questi pulsanti con CSS o utilizzare funzioni come anchor() per allinearli con precisione al tuo layout.
Indicatori di scorrimento con ::scroll-marker() e ::scroll-marker-group
I punti o le etichette sotto un carosello, spesso chiamati "indicatori di paginazione" o "segnalibri", sono un altro requisito comuneMostrano quanti elementi sono presenti e quale è attualmente visibile, e consentono agli utenti di passare direttamente a una diapositiva specifica.
Migliori ::scroll-marker() Lo pseudo-elemento fornisce questi indicatori senza la necessità di generare manualmente link di ancoraggio o span.Ogni indicatore è essenzialmente un sistema di navigazione. <a> Elemento creato dal browser, che punta all'elemento di scorrimento corrispondente e partecipa alla navigazione tramite tastiera e screen reader.
Per configurarlo, devi indicare al browser dove posizionare il gruppo di marcatori. con scroll-marker-groupe su quali elementi creare i marcatori. Una configurazione minima potrebbe essere la seguente:
.carousel { scroll-marker-group: after; }
.carousel > li::scroll-marker { content: " "; }
.carousel > li::scroll-marker:target-current { background: var(--accent); }
Il browser crea un ::scroll-marker-group il contenitore come fratello dello scroller e lo popola con un marcatore per ogni figlio selezionatoIn questo semplice esempio i marcatori vengono visualizzati come punti vuoti, ma puoi altrettanto facilmente utilizzare testo come "Stagione 1", icone o persino miniature modificando il content proprietà.
Cosa rende speciali questi indicatori rispetto a una semplice barra di scorrimento? è che sono veri e propri link di navigazione. Permettono agli utenti di saltare direttamente a posizioni significative e sono dotati di semantica utile: c'è un :target-current Stato che indica quale marcatore corrisponde alla diapositiva attualmente visualizzata o agganciata. Il supporto da tastiera si comporta come un focus group e i lettori di schermo possono visualizzarli come un controllo simile a una lista di schede.
Questa strategia è particolarmente efficace quando lo scorrimento rappresenta blocchi logici piuttosto che singoli elementi.Ad esempio, invece di creare dieci marcatori per dieci episodi, potresti crearne due che ti portano direttamente all'inizio della prima stagione e all'inizio della seconda. Sei libero di decidere quali "punti di interesse" rendere accessibili.
Combinazione di pulsanti e indicatori in un'interfaccia utente a carosello completa
Quando metti ::scroll-button() e ::scroll-marker() insieme sullo stesso cursoreIn questo modo, si ottiene un'interfaccia utente che gli utenti riconoscono immediatamente come un carosello: controlli precedente/successivo, una riga di indicatori che mostrano a che punto si trovano e uno scorrimento fluido tra le diapositive.
La differenza fondamentale rispetto ai classici slider JavaScript è che la maggior parte di questa logica ora risiede nel browser.I pulsanti e i marcatori sono elementi generati con ruoli ARIA corretti, integrati correttamente nell'ordine di tabulazione e con un approccio all'accessibilità progettato dai team del browser sottostante, anziché reinventato per ogni sito.
Questo approccio apporta numerosi vantaggi molto pratici.Funziona anche con JavaScript disabilitato, elimina lo sfarfallio dell'idratazione e i problemi di temporizzazione, riduce il Cumulative Layout Shift perché i controlli sono noti al momento del layout CSS e si integra perfettamente con animazioni basate sullo scorrimento o query sullo stato di scorrimento, qualora si desideri aggiungere un tocco di stile.
Sui dispositivi touch, l'esperienza è naturalmente ottimizzata per l'uso con le dita. perché il contenitore di scorrimento è ancora semplicemente uno scroller nativo. Sui desktop, la rotellina del mouse e l'input da tastiera funzionano come previsto e gli indicatori di focus sui controlli generati possono essere personalizzati per soddisfare le linee guida di progettazione e accessibilità.
Dal punto di vista della manutenzione, "fare meno, ottenere di più" diventa una descrizione piuttosto accurata.Invece di dover gestire la logica di molteplici implementazioni di caroselli in diversi progetti, ci si affida a funzionalità di piattaforma condivise e standardizzate che continueranno a migliorare nel tempo senza alcuno sforzo aggiuntivo da parte vostra.
Come far funzionare Scroll Snap in progetti reali
Anche se per un attimo ignoriamo i nuovi pseudo-elementi, la sola funzione scroll-snap è già più che sufficiente per molti caroselli di produzione.Il supporto dei browser per la funzione scroll-snap nei motori di rendering moderni è solido e il comportamento è prevedibile sia con la rotellina del mouse che con i gesti touch.
Nel caso più semplice, il tuo carosello HTML potrebbe essere un div con una serie di immagini all'internoPuoi assegnare a quel contenitore una classe come .carousel e lasciare le immagini secondarie non classificate; il CSS gestisce l'allineamento e lo scorrimento.
Accendendo scroll-behavior: smooth sul contenitoreLo scorrimento tra i punti di aggancio diventa piacevolmente animato anziché scattoso. Ciò è particolarmente evidente quando gli utenti cliccano sui marcatori o sui link di ancoraggio, oppure quando si attiva lo scorrimento a livello di programmazione in configurazioni ibride.
Ciascuna proprietà chiave dello scorrimento svolge un ruolo ben distinto. scroll-snap-type definisce l'asse e se l'aggancio è obbligatorio o solo un suggerimento; scroll-snap-align sui bambini specifica dove vengono bloccati nella visualizzazione (inizio, centro, fine); e scroll-snap-stop: always impedisce al browser di saltare i punti di aggancio durante lo scorrimento rapido.
Utilizzate insieme, queste proprietà consentono di impostare con precisione l'effetto desiderato per la giostra.—da uno snap delicato e tollerante, adatto a sezioni di contenuto ampie, a un comportamento rigoroso, scorrimento per scorrimento, perfetto per i banner principali in cui non si vuole mai atterrare "tra" gli elementi.
Poiché si tratta di puro CSS, è possibile adattare facilmente il layout in modo responsivo.. Con le media query, passa da una diapositiva per vista su schermi stretti a diverse per vista su desktop ampi, semplicemente cambiando il flex-basis di elementi. Non sono necessari breakpoint JavaScript, listener di ridimensionamento o ricalcoli della larghezza.
Pseudo-elementi sperimentali e rilevamento delle caratteristiche
I nuovi pseudo-elementi orientati al carosello—::scroll-button(), ::scroll-marker() e ::scroll-marker-group—sono potenti ma ancora relativamente freschiAl momento della stesura di questo testo, sono disponibili in Chrome 135 e versioni successive, spesso con l'utilizzo di flag sperimentali, e verranno gradualmente estesi ad altri motori di ricerca.
Poiché il supporto non è ancora universale, i siti di produzione dovrebbero affidarsi al rilevamento delle funzionalità e a meccanismi di fallback efficaci.. Il CSS ti dà il @supports La regola "at" consente di applicare regole in modo condizionale in base al riconoscimento delle proprietà.
Potresti definire una semplice barra di navigazione di fallback—un insieme di link o pulsanti che si trovano sotto il carosello—e che nascondono quella striscia quando il browser supporta i pulsanti di scorrimento nativi. Ad esempio:
.carousel-nav { display: flex; gap: 0.5rem; }
@supports (scroll-button-inline: both) { .carousel-nav { display: none; } }
Qui .carousel-nav può contenere collegamenti di ancoraggio creati manualmente che puntano alle diapositive tramite ID, piace <a href="#slide1">1</a>Nei browser che supportano la nuova proprietà `scroll-button`, vengono visualizzati i controlli nativi e la navigazione di fallback viene nascosta; nei browser meno recenti, la navigazione tramite link rimane, abbinata alla funzione `scroll-snap` per un'esperienza perfettamente fruibile.
Questa strategia ibrida consente di sperimentare in sicurezza le funzionalità di carosello di nuova generazione già da oggi., senza vincolarsi a un particolare motore o configurazione di flag. Man mano che il supporto dei browser matura, è possibile fare maggiore affidamento sugli pseudo-elementi e ridurre parte della struttura manuale.
Carousel con riproduzione automatica e animazioni keyframe, realizzati esclusivamente con CSS.
Un'altra richiesta comune è la riproduzione automatica: un carosello che avanza da solo, eventualmente mettendosi in pausa quando si passa il mouse sopra.Sebbene la riproduzione automatica presenti alcune limitazioni in termini di esperienza utente e accessibilità, è possibile ottenerla utilizzando esclusivamente animazioni CSS.
Un modello semplice consiste nell'animare la traslazione orizzontale della traccia di scorrimento..
@keyframes slide {
0%, 20% { transform: translateX(0); }
25%, 45% { transform: translateX(-100%); }
50%, 70% { transform: translateX(-200%); }
75%, 95% { transform: translateX(-300%); }
100% { transform: translateX(0); }
}
.autoplay-carousel { display: flex; animation: slide 12s infinite; }
.autoplay-carousel:hover { animation-play-state: paused; }
In questo esempio, i fotogrammi chiave rimangono fissi per intervalli di tempo a ciascun offset prima di passare alla diapositiva successiva.La sequenza si ripete alla fine, dando l'impressione di una presentazione a scorrimento su quattro diapositive. Passando il mouse sopra il carosello, l'animazione si mette in pausa, consentendo agli utenti di esaminare i contenuti senza dover contrastare un movimento continuo.
Nel rispetto degli utenti che preferiscono una riduzione del movimento per motivi di salute o di comfort., puoi racchiudere l'animazione in una media query:
@media (prefers-reduced-motion: reduce) { .autoplay-carousel { animation: none; } }
Ciò garantisce che nei sistemi in cui è richiesto un movimento ridotto, le diapositive rimangano statiche, disabilitando di fatto la riproduzione automatica pur consentendo lo scorrimento manuale o la navigazione tramite pulsanti/marcatori, ove previsti.
Un compromesso importante è che la riproduzione automatica basata sui fotogrammi chiave non si integra automaticamente con lo scroll-snap.Stai traducendo manualmente il contenuto anziché affidarti allo scorrimento nativo, quindi devi progettare l'animazione con attenzione per evitare diapositive parzialmente visibili e per mantenere la sincronizzazione con il layout.
Considerazioni sull'accessibilità per i caroselli CSS
L'accessibilità è un ambito in cui i caroselli basati su CSS possono davvero dare il meglio di sé., perché gran parte della logica complessa viene trasferita dal codice personalizzato ai comportamenti della piattaforma, che sono stati attentamente progettati e testati.
Quando si utilizza lo scorrimento nativo e lo scroll-snap, si ottiene automaticamente il supporto per tastiera, tocco e mouse.Gli utenti possono accedere allo scroller tramite il tasto Tab, utilizzare i tasti freccia per spostarsi, scorrere con il dito sui touchscreen e utilizzare la rotellina del mouse, senza bisogno di listener di eventi o gestori personalizzati.
I pulsanti di scorrimento e i marcatori sperimentali fanno un ulteriore passo avantiIl browser li crea con una semantica appropriata, li integra nell'ordine di tabulazione e ne mantiene lo stato, rendendo molto difficile dimenticare accidentalmente gli attributi ARIA o etichettarli in modo errato. I controlli carosello risultanti tendono ad essere più accessibili in modo coerente rispetto alle implementazioni personalizzate.
È ancora possibile e consigliabile aggiungere suggerimenti semantici alle aree del carosello.Ad esempio, contrassegnando il contenitore con role="region" e una descrittiva aria-label Aiuta gli utenti di screen reader a capire cosa rappresenta il componente:
<div class="carousel" role="region" aria-label="Product gallery">
<div class="carousel-item" aria-label="Slide 1 of 3">...</div>
</div>
Garantire indicatori di messa a fuoco visibili per tutti gli elementi interattivi rimane fondamentaleChe si tratti di pulsanti e link personalizzati o di pseudo-elementi generati dal browser, assicurati che i contorni di focus non vengano rimossi o resi troppo sottili per essere visti. Regola outline, outline-offset o modifiche dello sfondo secondo necessità per soddisfare i requisiti di contrasto.
Un'altra considerazione pratica riguarda le dimensioni del bersaglio da toccare.È consigliabile utilizzare controlli di almeno 44×44 pixel per rispettare le linee guida comuni sull'accessibilità, in modo che gli utenti non abbiano difficoltà a toccare frecce o punti su schermi più piccoli.
Per qualsiasi funzionalità di riproduzione automatica, offri agli utenti un controllo chiaro ed evita movimenti eccessivamente bruschi.. Fornire una pausa al passaggio del mouse o un pulsante di pausa esplicito e valutare la possibilità di disattivare la riproduzione automatica per impostazione predefinita se il contenuto è denso o ricco di testo. In combinazione con prefers-reduced-motionIn questo modo, il tuo carosello risulterà più accessibile a un pubblico più ampio.
Gestione dello scorrimento circolare o "infinito" con CSS
Un comportamento che le persone spesso richiedono è lo scorrimento circolare.: quando raggiungi l'ultima diapositiva e scorri ulteriormente, torni dolcemente alla prima, come una giostra fisica che gira all'infinito.
Oggi non esiste una proprietà CSS diretta che renda un contenitore di scorrimento intrinsecamente circolare.Senza duplicare i contenuti, uno scroller nativo avrà un inizio e una fine: una volta raggiunto l'ultimo elemento, un ulteriore scorrimento non consentirà di avanzare.
Gli autori delle specifiche sono consapevoli che molti caroselli dell'interfaccia utente si aspettano questo comportamento ciclicoC'è un vivo interesse nell'esplorare soluzioni a livello di piattaforma per lo scorrimento ciclico, in modo simile a come sono stati standardizzati i nuovi pulsanti e indicatori di scorrimento. Detto questo, al momento non è possibile chiedere a un browser di mandare a capo le posizioni di scorrimento in modo nativo con una singola dichiarazione CSS.
Nelle configurazioni puramente CSS, simulare un loop di solito significa animare le trasformazioni (come negli esempi di keyframe di autoplay) o accettare una fine lineare della sequenza.Se è assolutamente necessaria una continuità senza soluzione di continuità e non è possibile duplicare i contenuti, JavaScript rimane al momento lo strumento più flessibile.
La buona notizia è che nulla ti impedisce di combinare un carosello basato principalmente su CSS con un pizzico di JavaScript laddove questo apporti effettivamente valore.Potresti affidarti allo scroll-snap e ai pulsanti CSS per la navigazione quotidiana, per poi aggiungere qualche riga di codice per monitorare la posizione di scorrimento e passare dalla fine all'inizio quando necessario.
HTML/CSS contro JavaScript per caroselli ricchi di funzionalità e basati su schede
Un dilemma frequente per gli sviluppatori meno esperti è se un carosello di schede più complesso "debba" essere scritto in JavaScript.Spesso si pensa che, non appena si passa dalle semplici immagini alle schede responsive con vari componenti, il solo CSS smetta di essere sufficiente.
In pratica, la proprietà CSS scroll-snap funziona altrettanto bene per le schede interattive quanto per le immagini semplici.Finché ogni scheda è un blocco all'interno del contenitore di scorrimento, è possibile agganciarsi ad essa, animarla e sovrapporre stili aggiuntivi. Titoli, pulsanti, frammenti di testo e persino contenuti multimediali incorporati non modificano sostanzialmente il funzionamento.
Il punto di forza di JavaScript risiede nel comportamento condizionale e nella gestione di stati complessi.Se il tuo carosello deve filtrare dinamicamente le schede, riordinare le diapositive, sincronizzarsi con altri componenti, recuperare nuovi contenuti al volo o supportare una logica altamente personalizzata ("se si fa clic su questo punto, mostra quella scheda completamente diversa"), allora JavaScript può esprimere tale logica di business più facilmente del solo CSS.
Tuttavia, un numero sorprendente di cursori di uso quotidiano sono essenzialmente elenchi statici di elementi che avanzano linearmenteIn questi casi, utilizzare poche righe di CSS anziché importare una grande libreria JS è più semplice da comprendere e offre prestazioni migliori. Comprendere lo scroll-snap e i nuovi pseudo-elementi permette di riservare JavaScript ai rari casi in cui si rivela davvero utile.
Se stai ancora imparando lo sviluppo front-end, considerare i caroselli CSS come punto di partenza predefinito è un'ottima abitudine.Iniziate con HTML e CSS e ricorrete agli script solo quando incontrate un limite evidente. Questo vi permetterà di scoprire di più sulle funzionalità già presenti nella piattaforma e spesso porterà a codebase più snelle e pulite.
Facendo un passo indietro, l'insieme emergente di funzionalità CSS relative a scorrimento, aggancio, pulsanti, marcatori e query sullo stato di scorrimento. ha trasformato i caroselli da widget ricchi di script in componenti perlopiù dichiarativi. Facendo affidamento su scroll-snap per il comportamento di impaginazione principale, utilizzando ::scroll-button() e ::scroll-marker() Laddove supportato e applicando le migliori pratiche di rilevamento delle funzionalità e di accessibilità, è possibile realizzare caroselli veloci, robusti e più facili da gestire rispetto ai tradizionali slider basati su JavaScript, mantenendo al contempo la flessibilità necessaria per integrare JavaScript laddove la logica ciclica o le interazioni avanzate lo richiedano.