Karussell ohne externe Bibliothek
Scroll Snap ist CSS – kein JavaScript. Mit Tailwind CSS und wenigen Utility-Klassen entsteht ein Touch-fähiger Slider, der auf jedem Gerät nativ funktioniert. Alpine.js ergänzt Navigationspfeile, Dot-Indikatoren und Keyboard-Support ohne eine einzige externe Bibliothek zu laden.
Inhaltsverzeichnis
- 1. Warum Scroll Snap statt Slider-Bibliothek?
- 2. Grundstruktur: Container und Slides mit Tailwind CSS
- 3. Snap-Typen und Align-Optionen verstehen
- 4. Navigation mit Alpine.js: Pfeile und scrollTo
- 5. Dot-Indikatoren: Aktiven Slide mit IntersectionObserver erkennen
- 6. Mehrere Slides gleichzeitig sichtbar: peek und partial
- 7. Keyboard-Navigation und Accessibility
- 8. Autoplay mit Pause bei Hover und Fokus
- 9. Scroll Snap Slider vs. Bibliotheken im Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Warum Scroll Snap statt Slider-Bibliothek?
Slider-Bibliotheken wie Swiper, Splide oder Glide.js lösen das Karussell-Problem vollständig, aber mit einem erheblichen Preis: zusätzliche Abhängigkeiten, JavaScript-Overhead und oft hunderte Kilobyte an Code, von denen ein Projekt nur einen Bruchteil nutzt. In Hyvä-Themes-Projekten ist jQuery und Knockout.js bewusst ausgeschlossen – und auch externe Slider-Bibliotheken widersprechen dem Prinzip, möglichst wenig JavaScript zu laden, das nicht direkt zum Framework gehört. Der Tailwind CSS Scroll Snap Slider ist die Alternative: nativ im Browser, ohne Abhängigkeiten, mit Touch-Support aus der Box.
CSS Scroll Snap ist seit 2019 in allen modernen Browsern verfügbar und hat heute eine Browserunterstützung von über 97 Prozent. Der Mechanismus ist einfach: Der Container definiert den Snap-Typ, jede Slide definiert ihre Snap-Position. Der Browser übernimmt das Snapping nativ, inklusive Touch-Gesten auf Mobilgeräten, Momentum-Scrolling auf iOS und Maus-Scroll auf Desktop. Tailwind CSS stellt alle notwendigen Utilities bereit, ohne dass eigene CSS-Klassen geschrieben werden müssen. Alpine.js kommt nur dann ins Spiel, wenn Navigationspfeile, Dot-Indikatoren oder Autoplay benötigt werden – reine CSS-Slider ohne jegliches JavaScript sind ebenfalls möglich.
2. Grundstruktur: Container und Slides mit Tailwind CSS
Die Grundstruktur eines Tailwind CSS Scroll Snap Sliders besteht aus zwei Elementen: dem Scroll-Container und den Slide-Elementen darin. Der Container bekommt die Klassen flex overflow-x-auto snap-x snap-mandatory scroll-smooth. flex legt die Slides horizontal nebeneinander, overflow-x-auto erlaubt horizontales Scrollen, snap-x setzt den Snap-Achse auf die X-Richtung, snap-mandatory erzwingt, dass der Scroll immer auf einem Snap-Punkt endet, und scroll-smooth animiert den programmatischen Scroll sanft.
Jede Slide bekommt snap-start flex-shrink-0 w-full. snap-start setzt den Snap-Punkt am Anfang der Slide – beim Scrollen springt der Container immer so, dass der Slide-Anfang am linken Rand des Containers liegt. flex-shrink-0 verhindert, dass Flexbox die Slides zusammenstaucht. w-full gibt jeder Slide die volle Containerbreite. Das sind alle CSS-Klassen, die für einen funktionierenden Scroll-Snap-Slider nötig sind – ohne JavaScript, ohne externe Bibliothek. Auf mobilen Geräten funktioniert Touch-Swiping sofort out of the box.
<!-- Basic Tailwind CSS Scroll Snap Slider — no JavaScript needed -->
<div class="relative overflow-hidden rounded-2xl">
<!-- Scroll container: snap-x mandatory, horizontal flex -->
<div
id="slider"
class="flex overflow-x-auto snap-x snap-mandatory scroll-smooth gap-0"
style="-webkit-overflow-scrolling: touch; scrollbar-width: none;"
>
<!-- Each slide: full width, snap at start -->
<div class="snap-start flex-shrink-0 w-full">
<div class="bg-sky-600 text-white flex items-center justify-center h-64 text-2xl font-bold rounded-2xl">
Slide 1
</div>
</div>
<div class="snap-start flex-shrink-0 w-full">
<div class="bg-indigo-600 text-white flex items-center justify-center h-64 text-2xl font-bold rounded-2xl">
Slide 2
</div>
</div>
<div class="snap-start flex-shrink-0 w-full">
<div class="bg-violet-600 text-white flex items-center justify-center h-64 text-2xl font-bold rounded-2xl">
Slide 3
</div>
</div>
</div>
</div>
3. Snap-Typen und Align-Optionen verstehen
Tailwind CSS bietet mehrere Snap-Klassen, die unterschiedliche Verhaltensweisen steuern. snap-mandatory erzwingt, dass jedes Scroll-Ende auf einem Snap-Punkt landet – das Scroll kommt nie zwischen zwei Slides zum Stehen. snap-proximity ist weicher: Das Snapping greift nur, wenn der Scroll sich in der Nähe eines Snap-Punkts befindet. Für einen Slider ist snap-mandatory fast immer die richtige Wahl, weil es verhindert, dass zwei Slides halb sichtbar sind. Für scrollbare Galerien, bei denen der Nutzer an einer beliebigen Position stoppen können soll, ist snap-proximity natürlicher.
Bei den Slide-Alignment-Klassen gibt es snap-start, snap-center und snap-end. snap-start richtet den Snap-Punkt am Anfang des Elements aus – die Slide springt an den linken Rand des Containers. snap-center zentriert das Element im Container – ideal für einen Peek-Effekt, bei dem der vorherige und nächste Slide jeweils seitlich herausragen. snap-end richtet am Ende aus, was selten gebraucht wird. Für den klassischen Fullscreen-Slider ist snap-start die Standardwahl. Außerdem gibt es snap-always, das erzwingt, dass jedes Slide einen eigenen Snap-Punkt hat, auch wenn mehrere auf einmal sichtbar sind.
4. Navigation mit Alpine.js: Pfeile und scrollTo
Für Navigationspfeile und programmatisches Weiterschalten braucht der Tailwind CSS Scroll Snap Slider minimal Alpine.js. Das Alpine.js-Komponent verwaltet den aktuellen Slide-Index und scrollt den Container mit scrollTo() auf die richtige Position. Der Schlüssel: Da alle Slides gleich breit sind (w-full des Containers), ist die X-Position des n-ten Slides immer n × containerWidth. Das macht die Navigation ohne DOM-Traversal-Magie möglich.
Alpine.js erlaubt hier sehr kompakten Code. Das x-data-Attribut am Container-Wrapper definiert das Komponent mit dem aktuellen Index und den Scroll-Funktionen. Die Pfeil-Buttons nutzen @click, um prev() und next() aufzurufen. Die Scroll-Funktion berechnet die Zielposition und nutzt scrollTo({ left: target, behavior: 'smooth' }). Da scroll-smooth nur für CSS-getriggerte Scrolls gilt, muss das behavior: 'smooth' hier explizit im JavaScript angegeben werden, damit die Alpine.js-Navigation ebenfalls animiert ist.
<!-- Tailwind CSS Scroll Snap Slider with Alpine.js navigation -->
<div
x-data="{
current: 0,
total: 3,
slider() { return this.$refs.slider },
goTo(index) {
this.current = Math.max(0, Math.min(index, this.total - 1));
// Slide width equals container width (w-full slides)
const width = this.slider().offsetWidth;
this.slider().scrollTo({ left: this.current * width, behavior: 'smooth' });
},
prev() { this.goTo(this.current - 1); },
next() { this.goTo(this.current + 1); }
}"
class="relative overflow-hidden rounded-2xl"
>
<!-- Scroll container -->
<div
x-ref="slider"
class="flex overflow-x-auto snap-x snap-mandatory scroll-smooth"
style="-webkit-overflow-scrolling: touch; scrollbar-width: none;"
>
<div class="snap-start flex-shrink-0 w-full h-72 bg-sky-600 flex items-center justify-center text-white text-2xl font-bold">Slide 1</div>
<div class="snap-start flex-shrink-0 w-full h-72 bg-indigo-600 flex items-center justify-center text-white text-2xl font-bold">Slide 2</div>
<div class="snap-start flex-shrink-0 w-full h-72 bg-violet-600 flex items-center justify-center text-white text-2xl font-bold">Slide 3</div>
</div>
<!-- Previous button — hidden on first slide -->
<button
@click="prev()"
:class="current === 0 ? 'opacity-40 cursor-not-allowed' : 'hover:bg-white/30'"
class="absolute left-3 top-1/2 -translate-y-1/2 w-10 h-10 rounded-full bg-white/20 text-white flex items-center justify-center transition-all"
:disabled="current === 0"
aria-label="Vorherige Slide"
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/></svg>
</button>
<!-- Next button — hidden on last slide -->
<button
@click="next()"
:class="current === total - 1 ? 'opacity-40 cursor-not-allowed' : 'hover:bg-white/30'"
class="absolute right-3 top-1/2 -translate-y-1/2 w-10 h-10 rounded-full bg-white/20 text-white flex items-center justify-center transition-all"
:disabled="current === total - 1"
aria-label="Nächste Slide"
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/></svg>
</button>
</div>
5. Dot-Indikatoren: Aktiven Slide mit IntersectionObserver erkennen
Dot-Indikatoren zeigen an, welcher Slide gerade aktiv ist, und erlauben direktes Anspringen einer Slide. Die Herausforderung: Wenn der Nutzer per Touch wischt statt per Pfeil-Button navigiert, muss das Alpine.js-Komponent wissen, welcher Slide in den Sichtbereich gerollt ist. scrollLeft / containerWidth ist eine Näherung, aber nicht zuverlässig bei Snap-Momentum. Die sauberste Lösung ist der IntersectionObserver: Für jede Slide wird ein Observer registriert, der meldet, wenn die Slide zu mindestens 50 Prozent sichtbar ist. Ist das der Fall, wird der aktuelle Index entsprechend aktualisiert.
Alpine.js bietet mit x-init den richtigen Hook, um den IntersectionObserver zu initialisieren. Im x-init-Callback werden alle Slide-Elemente per querySelectorAll gesammelt, für jedes ein Observer erstellt, und bei Intersection-Ereignissen der current-Wert des Alpine.js-Datens aktualisiert. Die Dots selbst sind einfache Buttons in einer flexiblen Reihe. Mit :class="current === index ? 'bg-white' : 'bg-white/40'" wechselt die aktive Dot-Farbe reaktiv bei jedem Scroll-Ereignis.
6. Mehrere Slides gleichzeitig sichtbar: Peek und Partial
Nicht jeder Tailwind CSS Scroll Snap Slider zeigt genau eine Slide auf einmal. Produktkarusselle, Testimonial-Slider und Bildgalerien zeigen oft anderthalb oder zwei Slides gleichzeitig. Der "Peek"-Effekt – der nächste Slide lugt seitlich hervor – signalisiert dem Nutzer, dass weiterer Inhalt scrollbar ist. Das ist mit Tailwind CSS rein über CSS realisierbar: Der Container bekommt Padding rechts (pr-8 oder pr-16), die Slides bekommen eine feste Breite kleiner als 100 Prozent (w-4/5 oder w-[calc(100%-2rem)]).
Für responsive Varianten – eine Slide auf Mobilgeräten, zwei auf Tablets, drei auf Desktop – kombiniert man Tailwind-responsive-Präfixe. Die Slides bekommen w-full sm:w-1/2 lg:w-1/3, und der Container behält snap-x snap-mandatory. snap-always auf den Slides stellt sicher, dass auch bei mehreren sichtbaren Slides jede ihren eigenen Snap-Punkt hat. Das ermöglicht einen echten Step-by-Step-Slider auf Desktop und einen Fullscreen-Slider auf Mobilgeräten – alles mit Tailwind-Utilities, ohne Media-Query-JavaScript.
7. Keyboard-Navigation und Accessibility
Ein Tailwind CSS Scroll Snap Slider ohne Keyboard-Navigation ist für Tastaturnutzer und Screen-Reader nicht zugänglich. Die Mindestanforderungen für WCAG-Konformität: Pfeiltasten navigieren zwischen Slides, Tab erreicht interaktive Elemente innerhalb der Slides, und der aktive Slide ist für Screen-Reader erkennbar. Alpine.js erlaubt es, Keyboard-Events direkt am Container-Wrapper abzuhören: @keydown.left.window="prev()" und @keydown.right.window="next()" reagieren auf Pfeiltasten. Um Konflikte mit anderen Elementen auf der Seite zu vermeiden, sollte der Slider zunächst Fokus haben – @keydown statt @keydown.window ist dann die sicherere Variante.
Für Screen-Reader-Unterstützung bekommen die Slide-Container role="group" und aria-label="Slide N von M". Der Scroll-Container selbst bekommt role="region" und aria-label="Bildkarussell". Mit aria-live="polite" auf einem versteckten Status-Element kann man Screen-Reader informieren, wenn sich der aktive Slide ändert. Das ist mehr Aufwand als bei einer fertig konfigurierten Bibliothek wie Swiper, die Accessibility eingebaut hat – aber es ist vollständig kontrollierbar und fügt keinen Framework-Code hinzu.
8. Autoplay mit Pause bei Hover und Fokus
Autoplay-Slider sind unter Accessibility-Gesichtspunkten heikel: WCAG 2.1 verlangt, dass automatisch sich bewegende Inhalte pausierbar, stoppbar oder verlangsambar sind. Ein Tailwind CSS Scroll Snap Slider mit Autoplay muss deshalb bei Hover auf dem Container und bei Fokus auf einem interaktiven Element innerhalb des Sliders pausieren. Alpine.js implementiert das mit einem Interval in x-init und Event-Listenern auf dem Container-Wrapper.
Das Autoplay-Pattern mit Alpine.js: x-init startet das Interval mit setInterval() und speichert die ID. @mouseenter und @focusin am Wrapper rufen clearInterval() auf. @mouseleave und @focusout starten das Interval neu. Eine Alpine.js-Store-Variable paused kann optional einen Pause-Button steuern. Das Interval selbst ruft next() auf, das automatisch am letzten Slide zur ersten Slide zurückspringt (current = (current + 1) % total). Diese Implementierung ist vollständig, benötigt keine externe Bibliothek und respektiert Nutzerinteraktion.
<!-- Autoplay slider with pause on hover/focus — Alpine.js + Tailwind CSS -->
<div
x-data="{
current: 0,
total: 3,
intervalId: null,
paused: false,
init() {
this.startAutoplay();
},
goTo(index) {
this.current = ((index % this.total) + this.total) % this.total;
const width = this.$refs.slider.offsetWidth;
this.$refs.slider.scrollTo({ left: this.current * width, behavior: 'smooth' });
},
next() { this.goTo(this.current + 1); },
prev() { this.goTo(this.current - 1); },
startAutoplay() {
// Advance to next slide every 4 seconds
this.intervalId = setInterval(() => this.next(), 4000);
},
stopAutoplay() {
clearInterval(this.intervalId);
}
}"
@mouseenter="stopAutoplay()"
@mouseleave="startAutoplay()"
@focusin="stopAutoplay()"
@focusout="startAutoplay()"
class="relative overflow-hidden rounded-2xl"
>
<div x-ref="slider" class="flex overflow-x-auto snap-x snap-mandatory scroll-smooth" style="scrollbar-width: none;">
<div class="snap-start flex-shrink-0 w-full h-72 bg-sky-600 flex items-center justify-center text-white text-2xl font-bold">Slide 1</div>
<div class="snap-start flex-shrink-0 w-full h-72 bg-indigo-600 flex items-center justify-center text-white text-2xl font-bold">Slide 2</div>
<div class="snap-start flex-shrink-0 w-full h-72 bg-violet-600 flex items-center justify-center text-white text-2xl font-bold">Slide 3</div>
</div>
<!-- Dot indicators -->
<div class="absolute bottom-4 left-0 right-0 flex justify-center gap-2">
<template x-for="(_, i) in Array.from({ length: total })" :key="i">
<button
@click="goTo(i)"
:class="current === i ? 'bg-white w-6' : 'bg-white/50 w-2'"
class="h-2 rounded-full transition-all duration-300"
:aria-label="`Slide ${i + 1}`"
></button>
</template>
</div>
</div>
9. Scroll Snap Slider vs. Bibliotheken im Vergleich
Die Entscheidung zwischen einem nativen Tailwind CSS Scroll Snap Slider und einer dedizierten Bibliothek hängt von den Anforderungen ab. Der native Ansatz ist immer dann die bessere Wahl, wenn Touch-Support, Responsive-Layouts und einfache Navigation ausreichen. Bibliotheken sind dann sinnvoll, wenn sehr komplexe Features wie Fade-Übergänge, vertikale Slider mit komplexer Synchronisation oder spezifische Thumbnail-Navigation benötigt werden.
| Feature | Tailwind CSS Scroll Snap | Swiper / Splide | Empfehlung |
|---|---|---|---|
| Bundle-Größe | 0 KB JS (CSS-only) | 30–130 KB (min+gz) | Nativer Ansatz |
| Touch-Support | Nativ, kostenlos | Ja, inkl. Momentum | Gleichwertig |
| Fade-Transition | Nicht nativ | Eingebaut | Bibliothek bei Bedarf |
| Accessibility (ARIA) | Manuell | Eingebaut | Bibliothek bei komplexen Anforderungen |
| Abhängigkeiten | Keine | npm-Package, Updates | Nativer Ansatz |
Für die meisten E-Commerce- und Marketingseiten reicht der native Tailwind CSS Scroll Snap Slider vollständig aus. Produktbilder-Slider, Testimonial-Karusselle, Banner-Slider und Feature-Showcases haben in der Regel keine Anforderungen, die über das hinausgehen, was Scroll Snap plus Alpine.js leisten können. Der entscheidende Vorteil: Null externe Abhängigkeiten bedeuten keine Sicherheitsupdates, keine breaking changes durch npm-Paketaktualisierungen und keine Bundle-Aufblähung.
Mironsoft
Hyvä Themes, Tailwind CSS und Alpine.js für Magento 2
Slider und Karusselle für euren Magento-Shop?
Wir implementieren performante Slider-Komponenten mit Tailwind CSS Scroll Snap und Alpine.js – Touch-fähig, barrierefrei und ohne externe Bibliotheken, die euren Build vergrößern.
Produkt-Slider
Bildkarussell, Thumbnail-Navigation und Zoom für Produktdetailseiten
Banner-Slider
Hero-Banner mit Autoplay, Pause bei Hover und Dot-Navigation
Testimonials
Karussell für Kundenbewertungen mit Peek-Effekt und Keyboard-Navigation
10. Zusammenfassung
Der Tailwind CSS Scroll Snap Slider ist für die meisten Web-Projekte die beste Wahl für Karusselle und Slider: Er benötigt keine externen Abhängigkeiten, funktioniert mit Touch nativ auf allen modernen Geräten und lässt sich mit wenigen Tailwind-Utilities vollständig konfigurieren. Der Container definiert Snap-Typ und -Achse, die Slides definieren ihren Snap-Punkt. Alpine.js ergänzt Navigation, Dot-Indikatoren, Autoplay und Keyboard-Support ohne externe JavaScript-Bibliotheken hinzuzufügen. Für Hyvä-Themes-Projekte ist das die natürliche Wahl, weil es exakt den Prinzipien entspricht: Alpine.js, Tailwind CSS, kein jQuery, keine externen Bibliotheken.
Die Grenzen des nativen Ansatzes liegen bei sehr komplexen Anforderungen wie Fade-Übergängen zwischen Slides, 3D-Transformations-Effekten oder sehr spezifischen Accessibility-Anforderungen, die eine vollständig vorkonfigurierte ARIA-Implementierung erfordern. In diesen Fällen ist eine dedizierte Bibliothek wie Splide (unter 20 KB) eine vertretbare Entscheidung. Für alle anderen Anwendungsfälle gilt: CSS kann es, Tailwind macht es einfach, Alpine.js macht es interaktiv – und kein npm-Package kommt hinzu.
Tailwind CSS Scroll Snap Slider — Das Wichtigste auf einen Blick
Container-Klassen
flex overflow-x-auto snap-x snap-mandatory scroll-smooth – das sind alle CSS-Klassen für den Scroll-Container.
Slide-Klassen
snap-start flex-shrink-0 w-full für Fullscreen-Slides. Für Peek-Effekt: w-4/5 und snap-center.
Alpine.js Navigation
scrollTo({ left: index * width, behavior: 'smooth' }) – keine externe Bibliothek, kein jQuery, kein Swiper.
Autoplay pausieren
@mouseenter="stopAutoplay()" und @focusin="stopAutoplay()" – Pflicht für WCAG-Konformität.
11. FAQ: Tailwind CSS Scroll Snap Slider
1Was ist CSS Scroll Snap?
2Welche Tailwind-Klassen für den Slider?
flex overflow-x-auto snap-x snap-mandatory scroll-smooth. Slides: snap-start flex-shrink-0 w-full. Kein weiteres CSS nötig.3snap-mandatory vs. snap-proximity?
4Dot-Indikatoren ohne Bibliothek?
x-init. Bei 50% Sichtbarkeit der Slide wird current aktualisiert. Dots mit :class-Binding reaktiv.5iOS und Android Unterstützung?
-webkit-overflow-scrolling: touch. Über 97% Browserunterstützung weltweit.6Peek-Effekt implementieren?
w-4/5 setzen, snap-center verwenden. Nächste Slide lugt seitlich hervor – signalisiert scrollbaren Inhalt.7Alpine.js zwingend nötig?
8Autoplay bei Hover pausieren?
@mouseenter="stopAutoplay()" und @focusin="stopAutoplay()" am Wrapper. WCAG-Pflicht für animierte Inhalte.9Responsive Slide-Breiten?
w-full sm:w-1/2 lg:w-1/3 auf Slides: eine Slide auf Mobil, zwei auf Tablet, drei auf Desktop – rein mit Tailwind-Utilities.10Ist der Slider barrierefrei?
role="region", aria-label am Container, role="group" und aria-label="Slide N von M" an Slides, Keyboard-Events und aria-live für Statusänderungen.