Skapa avancerade CSS-karuseller utan JavaScript

Senaste uppdateringen: 05/24/2026
Författare: C SourceTrail
  • Modern CSS scroll-snap förvandlar enkla scrollers till smidiga, paginerade karuseller utan JavaScript.
  • Nya pseudoelement som ::scroll-button() och ::scroll-marker() genererar tillgängliga karusellkontroller i ren CSS.
  • CSS-enbart-strategier, i kombination med noggranna reservlösningar och ARIA, levererar snabba, robusta och inkluderande karuseller.
  • JavaScript blir valfritt och reserverat för kantfall som äkta oändlig looping eller komplext tillståndsfullt beteende.

CSS-karusell utan JavaScript

Att bygga karuseller med inget annat än modern CSS är inte längre en dröm—Det är ett mycket verkligt, produktionsklart alternativ som ofta kan överträffa klassiska JavaScript-sliderbibliotek. Tack vare funktioner som scroll snapping, scroll-drivna animationer, experimentella karusell-pseudoelement och robusta tillgänglighetsprimitiver, kan du leverera lätta, tåliga karuseller som ändå känns smidiga, interaktiva och polerade.

Om du är trött på att dra in 50KB JavaScript-paket bara för att visa några få bilder, den här guiden guidar dig igenom vad dagens CSS kan göra för dig. Vi kommer att gå igenom de viktigaste koncepten bakom CSS-bara karuseller, hur man kopplar ihop dem med scroll-snap, när man ska förlita sig på det nya ::scroll-button() och ::scroll-marker() pseudo-element, och hur man strö in autouppspelning eller cirkulärt beteende samtidigt som man behandlar tillgänglighet och prestanda som förstklassiga medborgare.

Varför CSS-bara karuseller äntligen är ett seriöst alternativ

I åratal var "karusell" nästan en synonym för "JavaScript-plugin".Lösningar som Swiper, Glide eller egenutvecklade reglage var det vanligaste tillvägagångssättet: de hanterade navigering, tillstånd, tangentbordsstöd och pekgester, men till bekostnad av extra vikt, händelselyssnare överallt och en hel del DOM-gymnastik.

Modern CSS har i tysthet täckt det mesta av den luckan. Med fastigheter som t.ex scroll-snap-type och scroll-snap-align, kan du förvandla vilken horisontell eller vertikal scroller som helst till en paginerad upplevelse. Dessutom introducerar CSS Overflow Level 5-specifikationen webbläsargenererad rullningsknappar och markörer som beter sig som ett fullfjädrat karusell-gränssnitt, men deklareras helt och hållet i CSS.

Den stora vinsten är att webbläsaren, inte din JavaScript-kod, blir ansvarig för centrala UX-problem.: rullningsfysik, tangentbordsnavigering, fokusordning och till och med ARIA-roller för karusellens kontroller. I många fall är det verkligen svårt att bygga något mer tillgängligt och bättre prestanda än vad plattformen nu ger dig direkt.

En annan stor fördel med CSS-karuseller är motståndskraftOm JavaScript inte laddas får användare med blockerat eller inaktiverat skript fortfarande en fullt användbar, rullbar uppsättning objekt. Det finns ingen hydrering, ingen layoutförändring som introduceras av sen kodinläsning och betydligt färre rörliga delar som kan gå fel med tiden.

Kärnbyggnadsblock: en rullningsbar behållare med Scroll Snap

Varje CSS-enbart karusell börjar som en vanlig rullningsbar behållareTänk dig en enkel lista med bilder som kan rullas horisontellt. Därifrån lägger du till rullningsfunktion så att visningsporten naturligt låses på varje bild.

En minimal HTML-struktur för en horisontell karusell är avsiktligt enkelett omslagselement och en serie bildobjekt inuti. Du kan använda en ul med li element, eller en div med barn divs—CSS gör det tunga arbetet, så du behöver inte specialklasser på varje barn om inte din design kräver det.

En grundläggande scroll-snap-inställning skulle kunna se ut så här i CSS, förutsatt en vy med en enda bild i full bredd:

.carousel { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth; }
.carousel-item { flex: 0 0 100%; scroll-snap-align: center; }

Här använder behållaren display: flex att rada upp sina barn horisontelltoch overflow-x: auto för att aktivera rullning. Magin ligger i scroll-snap-type: x mandatory, vilket talar om för webbläsaren att horisontell rullning alltid ska stanna vid en giltig fästpunkt, och i scroll-snap-align: center på varje bild, vilket definierar dessa fästpunkter.

Denna kombination av flexbox och scroll snap känns direkt som en karusell: användare skrollar eller sveper, och närmaste bild klickar på plats. Eftersom den använder inbyggd rullning fungerar pekinmatning på telefoner och surfplattor helt enkelt, utan några gesthanterare eller extra bibliotek.

Du är inte begränsad till ett objekt per visningFör karuseller med flera kolumner som visar flera kort samtidigt kan du använda en flexibel bredd för objekt, till exempel:

.carousel-item { flex: 0 0 calc(33.333% - 1rem); margin: 0 0.5rem; scroll-snap-align: center; }

Den här varianten låter dig visa, säg, tre kort per visningsport med lite mellanrum, samtidigt som de fortfarande drar nytta av snapping-beteendet. Användare glider igenom sidor med kort istället för att använda enskilda bilder, vilket fungerar utmärkt för produktlistor eller gallerier.

Scrollknappar med pseudoelementet ::scroll-button()

När du väl har en snapping scroller är nästa sak som de flesta vill ha tydliga navigeringsknappar—föregående och nästa kontroller som knuffar karusellen åt vänster eller höger. Traditionellt skulle du skapa <button> element, binda klickhändelser och beräkna hur långt man ska scrolla.

CSS Overflow 5-specifikationen introducerar ::scroll-button(), ett pseudoelement som låter webbläsaren göra allt det där tunga arbetetÄven om detta för närvarande är tillgängligt från och med Chrome 135 (och vanligtvis bakom experimentella flaggor till en början), är det en glimt av hur karuseller kommer att skapas framöver.

Du deklarerar rullknappar på samma sätt som du skulle göra med vilket annat pseudoelement som helst.Till exempel, för att generera vänster- och högerknappar för din karusell:

.carousel::scroll-button(left) { content: "⬅" / "Scroll left"; }
.carousel::scroll-button(right) { content: "⮕" / "Scroll right"; }
.carousel::scroll-button(*) :focus-visible { outline-offset: 5px; }

När denna CSS appliceras skapar webbläsaren faktiskt riktiga <button> element som syskon till rullningsbehållaren, kopplar dem till scrollern, tilldelar lämpliga roller och styr deras beteende. Ett enda klick scrollar vanligtvis runt 85 % av scrollytan, vilket känns som en "sida" i de flesta karuselllayouter.

Om din design förväntar sig exakt ett objekt i full bredd per klick, kan du kombinera dessa pseudoelement med striktare snapping på varje barn genom att lägga till scroll-snap-stop: alwaysDet tvingar visningsporten att landa på objektgränser istället för att stanna halvvägs.

Innehållsegenskapen här tjänar dubbeltDet första värdet är vad användarna visuellt ser (i det här fallet piltecken), och den andra strängen är tillgänglig reservtext som kan visas för hjälpmedelsteknik. Du kan fritt utforma och placera dessa knappar med CSS, eller använda funktioner som anchor() för att justera dem exakt med din layout.

Scrollmarkörer med ::scroll-marker() och ::scroll-marker-group

Punkter eller etiketter under en karusell – ofta kallade ”sidningspunkter” eller ”markörer” – är ett annat vanligt krav.De visar hur många objekt som finns och vilket som är synligt för närvarande, och de låter användare hoppa direkt till en specifik bild.

Ocuco-landskapet ::scroll-marker() pseudo-elementet ger dig dessa indikatorer utan att manuellt generera ankarlänkar eller spannVarje markör är i huvudsak en navigeringsfunktion <a> element som skapas av webbläsaren, vilket pekar på motsvarande rullningsobjekt och deltar i navigering med tangentbord och skärmläsare.

För att ställa in detta anger du för webbläsaren var markörgruppen ska placeras. med scroll-marker-group, och på vilka element markörer ska skapas. En minimal konfiguration kan se ut så här:

.carousel { scroll-marker-group: after; }
.carousel > li::scroll-marker { content: " "; }
.carousel > li::scroll-marker:target-current { background: var(--accent); }

Webbläsaren bygger en ::scroll-marker-group containern som en syskon till scrollern och fyller den med en markör för varje valt barnI det här enkla exemplet återges markörerna som tomma punkter, men du kan lika gärna använda text som "Säsong 1", ikoner eller till och med miniatyrbilder genom att ändra content fast egendom.

Vad gör dessa markörer speciella jämfört med en vanlig rullningslist är att de är riktiga navigeringslänkar. De låter användare hoppa direkt till meningsfulla positioner, och de har användbar semantik: det finns en :target-current tillstånd som anger vilken markör som motsvarar den bild som för närvarande visas eller har fästs. Tangentbordsstödet fungerar som en fokusgrupp, och skärmläsare kan visa dem som en tabellistliknande kontroll.

Den här strategin är särskilt kraftfull när din scroller representerar logiska bitar snarare än enskilda objektTill exempel, istället för att skapa tio markörer för tio avsnitt, kan du skapa två markörer som hoppar till början av säsong ett och säsong två. Du kan fritt bestämma vilka "intressanta punkter" som ska vara adresserbara.

Kombinera knappar och markörer till ett komplett karusellgränssnitt

När du lägger ::scroll-button() och ::scroll-marker() tillsammans på samma scroller, får du ett användargränssnitt som användarna direkt känner igen som en karusell: föregående/nästa-kontroller, en rad markörer som visar hur långt fram de har kommit och smidig fästning mellan bilderna.

Den viktigaste skillnaden från klassiska JavaScript-sliders är att det mesta av denna logik nu finns i webbläsaren.Knappar och markörer är genererade element med korrekta ARIA-roller, korrekt integrerade i tabbordningen och en tillgänglighetsberättelse utformad av de underliggande webbläsarteamen snarare än att återuppfinnas för varje webbplats.

Denna metod medför flera mycket praktiska fördelarDen fungerar med JavaScript inaktiverat, eliminerar hydreringsflimmer och timingproblem, minskar kumulativ layoutförskjutning eftersom kontrollerna är kända vid CSS-layouttillfället och integreras sömlöst med rullningsdrivna animationer eller rullningsstatusfrågor om du vill lägga till stil.

På pekskärmar är upplevelsen naturligtvis fingervänlig eftersom rullningsbehållaren fortfarande bara är en inbyggd rullningsfunktion. På skrivbordsmiljöer fungerar mushjul och tangentbordsinmatning som förväntat, och fokusindikatorer på genererade kontroller kan utformas för att uppfylla dina design- och tillgänglighetsriktlinjer.

Ur ett underhållsperspektiv blir "gör mindre, nå mer" en ganska korrekt beskrivningIstället för att bibehålla logiken med flera karusellimplementeringar över projekt, förlitar ni er på delade, standardiserade plattformsfunktioner som kommer att förbättras över tid utan extra arbete från er sida.

Få Scroll Snap att fungera i verkliga projekt

Även om du ignorerar de nya pseudoelementen för ett ögonblick, räcker scroll-snap ensamt redan för många produktionskaruseller.Webbläsarstödet för scroll-snap i moderna motorer är stabilt, och beteendet är förutsägbart både med mushjul och pekgester.

I det enklaste scenariot kan din HTML-karusell vara en div med en serie bilder inutiDu kan ge den containern en klass som .carousel och lämna barnbilderna oklassificerade; CSS hanterar justering och rullning.

Genom att slå på scroll-behavior: smooth på behållarenblir rullning mellan snappunkter behagligt animerad istället för hoppig. Detta märks särskilt när användare klickar på markörer eller ankarlänkar, eller när du utlöser rullning programmatiskt i hybridinställningar.

Varje tangent scroll-snap-egenskap spelar en mycket distinkt roll. scroll-snap-type definierar axeln och om snapping är obligatorisk eller bara en ledtråd; scroll-snap-align på underordnade anger var de låses i vyn (start, mitt, slut); och scroll-snap-stop: always förhindrar att webbläsaren hoppar över fästpunkter vid snabb scrollning.

Tillsammans låter dessa egenskaper dig justera exakt hur karusellen ska kännas—från mjuk, förlåtande snapping lämplig för stora innehållsavsnitt, till strikt, bild-för-bild-beteende perfekt för hero-banners där du aldrig vill landa "mellan" objekt.

Eftersom detta är ren CSS kan du enkelt anpassa layouten responsivtMed mediefrågor kan du växla från en bild per vy på smala skärmar till flera per vy på breda skrivbord, bara genom att ändra flex-basis av objekt. Inga JavaScript-brytpunkter, storleksändring av lyssnare eller omberäknade bredder krävs.

Experimentella pseudoelement och funktionsdetektering

De nya karusellorienterade pseudoelementen—::scroll-button(), ::scroll-marker() och ::scroll-marker-group—är kraftfulla men fortfarande relativt färskaI skrivande stund är de tillgängliga i Chrome 135 och senare, ofta med krav på experimentella flaggor, och de kommer att lanseras till andra motorer med tiden.

Eftersom stödet ännu inte är universellt bör produktionsplatser förlita sig på funktionsidentifiering och smidiga alternativ.CSS ger dig @supports at-rule, som låter dig villkorligt tillämpa regler baserade på egenskapsigenkänning.

Du kan definiera en enkel reservnavigeringsremsa—en uppsättning länkar eller knappar som sitter under karusellen—och sedan döljer den remsan när webbläsaren stöder inbyggda rullningsknappar. Till exempel:

.carousel-nav { display: flex; gap: 0.5rem; }
@supports (scroll-button-inline: both) { .carousel-nav { display: none; } }

Här .carousel-nav kan innehålla handskrivna ankarlänkar som pekar på bilder via ID:n, tycka om <a href="#slide1">1</a>I webbläsare som använder den nya scroll-button-egenskapen visas dina inbyggda kontroller och reservnavigeringen är dold. I äldre webbläsare finns ankarnavigeringen kvar, i kombination med scroll-snap, för en perfekt användbar upplevelse.

Denna hybridstrategi gör det säkert att experimentera med nästa generations karusellfunktioner idag, utan att låsa dig till en viss motor eller flaggkonfiguration. Allt eftersom webbläsarstödet mognar kan du luta dig mer mot pseudoelementen och trimma en del av den manuella strukturen.

CSS-endast autoplay-karuseller med nyckelbilds-animationer

En annan vanlig begäran är autoplay – en karusell som går vidare av sig själv, och pausar eventuellt när man håller muspekaren över den.Även om autoplay har vissa förbehåll gällande UX och tillgänglighet, är det möjligt att uppnå det enbart med CSS-animationer.

Ett enkelt mönster är att animera den horisontella förskjutningen av ditt bildspår.

@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; }

I det här exemplet tillbringar nyckelbildrutorna bitar av tid vid varje förskjutning innan de går vidare till nästa bild.Spåret loopas tillbaka i slutet och ger intrycket av ett upprepande bildspel över fyra bilder. Om du håller muspekaren över karusellen pausas animationen, så att användarna kan granska innehållet utan att behöva vara i konstant rörelse.

Att respektera användare som föredrar minskad rörelsefrihet av hälso- eller komfortskäl, kan du linda in animationen i en mediafråga:

@media (prefers-reduced-motion: reduce) { .autoplay-carousel { animation: none; } }

Detta säkerställer att bilderna förblir statiska på system där minskad rörelse önskas, vilket effektivt inaktiverar autouppspelning samtidigt som manuell rullning eller knapp-/markörnavigering fortfarande är tillåten där det tillhandahålls.

En viktig avvägning är att autoplay baserad på nyckelbildrutor inte integreras automatiskt med scroll-snap.Du översätter innehållet manuellt snarare än att förlita dig på inbyggd scrollning, så du måste utforma animationen noggrant för att undvika halvt synliga bilder och för att hålla timingen synkroniserad med din layout.

Tillgänglighetsöverväganden för CSS-karuseller

Tillgänglighet är ett område där CSS-baserade karuseller verkligen kan glänsa, eftersom mycket av den tunga logiken skiftar från din anpassade kod till plattformsbeteenden som har noggrant utformats och testats.

När du använder inbyggd rullning plus scroll-snap ärver du automatiskt stöd för tangentbord, pekskärm och mus.Användare kan använda tabbtangenterna för att scrolla, använda piltangenterna för att flytta, svepa på pekskärmar och scrolla med ett hjul, utan händelselyssnare eller anpassade hanterare.

De experimentella rullningsknapparna och markörerna går ett steg längreWebbläsaren skapar dem med lämplig semantik, integrerar dem i tabbordningen och bibehåller deras tillstånd, vilket gör det mycket svårt att av misstag glömma ARIA-attribut eller felmärka dem. De resulterande karusellkontrollerna tenderar att vara mer konsekvent tillgängliga än heminriktade implementeringar.

Du kan och bör fortfarande lägga till semantiska tips i dina karusellregionerTill exempel att märka behållaren med role="region" och en beskrivande aria-label hjälper skärmläsaranvändare att förstå vad komponenten representerar:

<div class="carousel" role="region" aria-label="Product gallery">
<div class="carousel-item" aria-label="Slide 1 of 3">...</div>
</div>

Att säkerställa synliga fokusindikatorer för alla interaktiva element är fortfarande avgörandeOavsett om kontrollerna är dina egna knappar och länkar eller webbläsargenererade pseudoelement, se till att fokuskonturerna inte tas bort eller görs för subtila för att synas. Justera outline, outline-offset eller bakgrundsändringar efter behov för att uppfylla kontrastkraven.

Storleken på pekskärmen är en annan praktisk faktorSikta på kontroller som är minst 44×44 pixlar för att följa vanliga tillgänglighetsriktlinjer, så att användarna inte har svårt att trycka på pilar eller punkter på mindre skärmar.

För alla autospelningsfunktioner, ge användarna tydlig kontroll och undvik alltför aggressiva rörelser. Tillhandahåll en pausknapp vid muspekning eller en tydlig pausknapp, och överväg att avaktivera automatisk uppspelning som standard om innehållet är tätt eller texttungt. Kombinera med prefers-reduced-motion, detta gör din karusell mer bekväm för en bredare publik.

Hantera cirkulär eller "oändlig" rullning med CSS

Ett beteende som folk ofta efterfrågar är cirkulär scrollningNär du når den sista bilden och skrollar vidare, hoppar du smidigt tillbaka till den första, som en fysisk karusell som snurrar oändligt.

Idag finns det ingen direkt, renodlad CSS-egenskap som gör en scroll-container i sig cirkulär.Utan att duplicera innehåll kommer en inbyggd scroller att ha en början och ett slut: när du väl når det sista objektet kommer du helt enkelt inte att kunna scrolla vidare.

Specifikationsförfattare är medvetna om att många UI-karuseller förväntar sig detta loopbeteende., och det finns ett aktivt intresse för att utforska lösningar på plattformsnivå för cyklisk rullning, ungefär på samma sätt som nya rullningsknappar och markörer standardiserades. Med det sagt kan man för närvarande inte be en webbläsare att radbryta rullningspositioner direkt med en enda CSS-deklaration.

I rena CSS-upplägg innebär simulering av looping vanligtvis att animera transformationer (som i exempel på autoplay-nyckelbilder) eller att acceptera ett linjärt slut på sekvensen.Om sömlös oändlighet är absolut nödvändig och du inte kan duplicera innehåll, är JavaScript fortfarande det mer flexibla verktyget för tillfället.

Den goda nyheten är att ingenting hindrar dig från att kombinera en mestadels CSS-driven karusell med en liten mängd JavaScript där det verkligen ger mervärde.Du kan förlita dig på scroll-snap- och CSS-knappar för daglig navigering, och sedan lägga till några rader skript för att övervaka scrollpositionen och hoppa från början till slut när det är lämpligt.

HTML/CSS kontra JavaScript för rika, kortbaserade karuseller

Ett vanligt dilemma för nyare utvecklare är om en mer komplex kortkarusell "måste" skrivas i JavaScript.Folk föreställer sig ofta att så fort man går bortom enkla bilder och nu över till responsiva kort med olika komponenter, så slutar CSS ensamt att vara gångbart.

I praktiken fungerar CSS scroll-snap lika bra för rich cards som för vanliga bilder.Så länge varje kort är ett block i rullningsbehållaren kan du fästa mot det, animera runt det och lägga till ytterligare stilar ovanpå. Titlar, knappar, textfragment och till och med inbäddade medier förändrar inte mekanismen i grunden.

Där JavaScript lyser är i villkorligt beteende och komplext tillståndOm din karusell måste dynamiskt filtrera kort, ändra ordning på bilder, synkronisera med andra komponenter, hämta nytt innehåll i farten eller stödja mycket anpassad logik ("om den här punkten klickas, visa det helt orelaterade kortet"), så kan JavaScript uttrycka den affärslogiken enklare än enbart CSS.

Emellertid är ett överraskande antal vardagliga reglage i huvudsak statiska listor med objekt som fortskrider linjärt.I dessa fall är det både enklare att resonera kring och bättre för prestandan att använda några rader CSS istället för att importera ett stort JS-bibliotek. Att förstå scroll-snap och de nyare pseudoelementen låter dig reservera JavaScript för de sällsynta fall där det verkligen lönar sig.

Om du fortfarande lär dig frontend-utveckling är det en bra vana att använda CSS-karuseller som din standardbaslinje.Börja med HTML och CSS, och använd bara skript när du stöter på en tydlig begränsning. Detta lär dig mer om vad plattformen redan kan göra och leder ofta till smidigare och renare kodbaser.

Ett steg tillbaka, den framväxande uppsättningen CSS-funktioner kring rullning, snapping, knappar, markörer och rullningsfrågor. har omvandlat karuseller från skripttunga widgetar till mestadels deklarativa komponenter. Genom att förlita sig på scroll-snap för kärnbeteendet i paging, med hjälp av ::scroll-button() och ::scroll-marker() Där det stöds, och med tillämpning av bästa praxis för funktionsidentifiering och tillgänglighet, kan du leverera karuseller som är snabba, robusta och enklare att underhålla än traditionella JS-drivna reglage – samtidigt som du behåller tillräckligt med flexibilitet för att blanda in JavaScript där cyklisk logik eller avancerade interaktioner verkligen kräver det.

egendom css touch-action
Relaterad artikel:
Propiedad CSS touch-action: cómo domar gestos taktiles con precision
Relaterade inlägg: