Galerie✨ Premium

Card Carousel

Rangée de cartes qui avance d'une carte à la fois, aux flèches ou au doigt, et s'arrête net quand la dernière est entièrement visible.

CSSMultiScroll

Mis à jour le

Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Galerie comprend 44 effets, dont 6 gratuits. Découvrir la catégorie →

3 exemples d'usage

« Vous aimerez aussi » sous la fiche d'un roman — Card Carousel exemple 1

① « Vous aimerez aussi » sous la fiche d'un roman

QuandSur la librairie en ligne Lisoranne, la fiche de « La Maison des marées » (couverture, résumé, bouton Ajouter au panier) se termine par une rangée de huit couvertures de romans suggérés, titre en bas de chaque couverture. Les flèches font défiler la sélection une couverture à la fois.
PourquoiLes suggestions ne prennent qu'une ligne sous la fiche au lieu d'une grille entière, et l'avancée carte par carte garde chaque couverture lisible pendant le déplacement. La butée en fin de rangée dit clairement qu'il n'y a plus rien après.
Réglages--ccr-max-width: none, cartes de 92 × 138 px (--ccr-card-w, --ccr-card-h), une <img> de couverture + titre en HTML dans chaque carte, flèches foncées (CSS de la scène). Dans la capture, la démo clique la vraie flèche toutes les 0,9 s et repart en arrière au bout de la rangée.
Formules d'une salle d'escalade sur mobile — Card Carousel exemple 2

② Formules d'une salle d'escalade sur mobile

QuandSur la page Tarifs de la salle Grimpevelle, vue sur téléphone : quatre cartes de formule (découverte, carnet de 10, annuel, étudiant) avec prix, conditions et bouton Choisir. Une carte remplit presque l'écran et le bord de la suivante dépasse : on balaie du pouce pour comparer.
PourquoiSur un petit écran, quatre colonnes de prix seraient illisibles ; en carrousel chaque formule garde sa taille normale, et le bord visible de la carte suivante invite au geste. La formule mise en avant (annuel, en orange) reste une carte comme les autres.
RéglagesCartes de 128 × 206 px, écart de 10 px (--ccr-gap), flèches masquées (CSS de la scène) car le geste suffit sur mobile. La capture envoie au vrai code un pointerdown puis un pointerup tactiles toutes les secondes et change de sens en bout de rangée ; le rond blanc est un repère de la scène.
Bandeau de dates dans un widget de réservation — Card Carousel exemple 3

③ Bandeau de dates dans un widget de réservation

QuandSur la page du restaurant Le Tavelin, le widget « Réserver une table » montre une petite rangée de jours (jour, date, tables libres ou « complet »), avec des flèches de 22 px de chaque côté ; dessous, les heures, le nombre de couverts et le bouton Réserver.
PourquoiL'effet devient un sélecteur compact : dix jours tiennent dans 160 px de large, et la butée en fin de période évite de laisser croire qu'il reste des dates. Utilisé en petit détail, il ne prend pas plus de place qu'un champ de formulaire.
RéglagesCartes de 44 × 58 px, écart de 6 px, flèches réduites à 22 px et placées hors de la piste (marges de 26 px), jour sélectionné en brique (CSS de la scène). La démo clique la vraie flèche toutes les 0,8 s dans la capture.

Comment ça marche

La racine .fx-0166-root contient un .ccr-slider : une fenêtre .ccr-viewport qui masque ce qui dépasse, une piste .ccr-track en flex avec 12 px d'écart, et deux flèches rondes en verre dépoli posées sur les bords. Chaque .ccr-card mesure 140 × 180 px par défaut et grossit de 5 % au survol ou quand un élément qu'elle contient a le focus.

Le pas n'est pas écrit en dur : à l'ouverture et à chaque changement de taille (ResizeObserver), le script mesure la largeur réelle d'une carte et l'écart de la piste, puis la distance maximale à parcourir pour que la dernière carte touche le bord droit. Une flèche ou un glisser de plus de 50 px décale la piste d'un pas (translateX, 0,4 s) ; arrivé au bout, la piste s'arrête au pixel près et la flèche correspondante passe à aria-disabled="true" (opacité 35 %). Pas de boucle.

Le carrousel occupe la largeur de son conteneur (640 px au plus par défaut) : plus il est large, plus il montre de cartes et moins il y a de pas. Une <img> posée dans une carte la couvre ; on peut aussi y mettre du texte, un prix, un bouton. Chaque .fx-0166-root de la page a sa propre instance.

Accessibilité

  • Flèches nommées : vrais boutons « Cartes précédentes » / « Cartes suivantes », signalés aria-disabled en bout de rangée, avec contour :focus-visible.
  • Cartes hors champ : toute carte qui n'est pas entièrement visible devient inert ; un lien qu'elle contient ne peut pas recevoir le focus et faire sauter la rangée.
  • Rôles : région aria-roledescription="carrousel" nommée, cartes role="group" annoncées « carte, 3 sur 6 » (textes dans le HTML, à traduire).
  • Mouvement réduit : sous prefers-reduced-motion: reduce, la rangée et l'agrandissement au survol changent sans transition.
  • Toucher : Pointer Events et touch-action: pan-y : on balaie la rangée horizontalement sans empêcher le défilement vertical de la page.

Compatibilité navigateur

JavaScript sans dépendance : ResizeObserver (Chrome 64, Firefox 69, Safari 13.1), Pointer Events, inert (Chrome 102, Firefox 112, Safari 15.5 d'après MDN). Mesuré dans Chromium 151, Firefox 153 et WebKit 26.5 (Playwright) : deux rangées dont la 2e pilotée seule, butée en fin de rangée, mouvement réduit, 390 px sans débordement, glisser au doigt (Chromium) sans bloquer le défilement vertical, 0 erreur.

Chrome 102+✓ Complet (mesuré)
Firefox 112+✓ Complet (mesuré)
Safari 15.5+✓ Complet (mesuré dans WebKit)
Edge 102+✓ Complet (moteur Chromium)
Mobile iOS 15.5+✓ Moteur WebKit, non vérifié sur appareil
Android Chrome 102+✓ Complet (toucher mesuré)

Sans JavaScript, la rangée affiche les premières cartes et les flèches ne font rien. Avant Safari 15.5 / Firefox 112, inert est ignoré : la navigation marche, mais une carte hors champ peut recevoir le focus.

Le code

Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :

index.html — structure
<div class="fx-0166-root">
  <div class="ccr-slider" role="region" aria-roledescription="carrousel" aria-label="…">
    <div class="ccr-viewport">
      <div class="ccr-track">
        <div class="ccr-card" role="group" aria-roledescription="carte" aria-label="1 sur 6">…</div>
        …
      </div>
    </div>
    <button class="ccr-arrow ccr-prev" type="button" aria-label="…">…</button>
    <button class="ccr-arrow ccr-next" type="button" aria-label="…">…</button>
  </div>
</div>

Paiement unique, sans abonnement — le code est à toi pour toujours

Personnaliser

Options passées à l'API ou attributs data-* :

Option / propriétéDéfautEffet
Largeur maximale (CSS — --ccr-max-width) 640px La rangée prend la largeur de son conteneur jusqu'à cette limite. none pour toute la largeur.
Taille des cartes (CSS — --ccr-card-w / --ccr-card-h) 140px / 180px Le pas de défilement suit automatiquement la largeur réelle des cartes.
Écart entre cartes (CSS — --ccr-gap) 12px Ajouté au pas : une flèche décale toujours d'exactement une carte et un écart.
Contenu des cartes (HTML — .ccr-card) 6 dégradés « Card 1 » à « Card 6 » Image (<img> qui couvre la carte), texte, prix, bouton. Mettez à jour les aria-label « X sur N » si vous en ajoutez.
Agrandissement au survol (CSS — .ccr-card:hover) scale(1.05), 0,3 s Supprimez la règle si vos cartes contiennent du texte qui doit rester fixe.
Flèche inactive (CSS — .ccr-arrow[aria-disabled="true"]) opacité .35 Apparence de la flèche en bout de rangée ; mettez display:none pour la cacher.

FAQ

Elle s'éteint quand la dernière carte touche le bord droit : il n'y a plus rien à révéler. Dans une zone large, il peut n'y avoir qu'un ou deux pas ; si toutes les cartes tiennent, les deux flèches sont inactives.
Le pas est mesuré sur la première carte : avec des largeurs différentes, l'avancée ne tombera pas pile sur un bord de carte. Gardez une largeur commune (--ccr-card-w) et faites varier le contenu.
Ce carrousel ne boucle pas, c'est voulu : il s'arrête quand la dernière carte est visible. Pour une rangée sans fin, il faut un effet de bande défilante plutôt qu'un carrousel à pas.