GalerieGratuit

CSS-Only Carousel

Carrousel sans une ligne de JavaScript : défilement aimanté au doigt, au trackpad et au clavier partout, flèches et pastilles natives dans Chrome et Edge 135+.

CSS natif0 JSscroll-marker

Mis à jour le

Survolez ou cliquez la scène pour interagir

Cet effet est gratuit — la catégorie Galerie en contient 44 au total, dont 6 gratuits. Effect.Labs regroupe 840 effets vanilla. Découvrir la catégorie →

Exemples d'usage

Nos réalisations

Conception, plantation et entretien de jardins privés dans un rayon de 40 km.

Demander un devis

① Les réalisations d'un paysagiste, à feuilleter au doigt

QuandSur le site vitrine du paysagiste Verdaline, un court texte de présentation et le bouton « Demander un devis » sont à gauche ; à droite, la rangée de cinq jardins (potager, bassin, terrasse, prairie, haie) avec le nom et la ville en légende. Sur téléphone, le texte disparaît et la rangée prend toute la largeur.
PourquoiLe visiteur parcourt les photos comme dans une galerie de téléphone, sans attendre un script. La diapositive suivante dépasse sur le bord droit : on comprend tout de suite qu'il y a une suite à faire glisser.
Réglages--coc-max-width: none, --coc-slide-width: 80%, --coc-ratio: 4/3, une <img> par diapositive (illustration SVG) et une légende en HTML ; pastilles recolorées en vert pour rester visibles sur le fond beige (CSS de la scène). La scène est vivante : essayez le glisser, Maj + molette ou les flèches.

Chaque cocktail existe sans alcool : demandez au bar.

② Les cocktails d'un bar, une fiche par pastille

QuandSur la carte en ligne du bar Brumeline, onglet Cocktails : une fiche à la fois (verre illustré, nom, ingrédients, degré, prix), les pastilles sous la fiche pour sauter directement au quatrième cocktail, les flèches de chaque côté. Une phrase rappelle que tout existe sans alcool.
PourquoiChaque cocktail a toute la place pour son illustration et sa description, et les pastilles servent de sommaire. Dans Firefox et Safari la carte reste consultable en faisant glisser.
Réglages--coc-slide-width: 100% (une fiche par vue), --coc-ratio: auto et hauteur de 180 px posée par la scène, fiches sur fond bleu nuit. Sur un écran étroit l'illustration est masquée et le texte garde la place.
Novembre
Solde2 418 €
Dépensé ce mois1 163 €
Logement
Courses
Transport
Sorties
Abonnements
Astuce du jour · touches ← →

③ L'astuce du jour dans une appli de budget, au clavier

QuandDans le tableau de bord de Tirelune, à côté du solde, des dépenses du mois et d'un petit graphique par catégorie, un encart violet « Astuce du jour » contient quatre conseils courts. On clique l'encart (ou on y arrive au Tab) et les touches ← → passent d'un conseil à l'autre ; les pastilles indiquent où l'on en est.
PourquoiC'est un petit détail secondaire : il ne doit ni bouger seul ni prendre de place. Le défilement natif au clavier suffit, sans bouton supplémentaire.
Réglages--coc-slide-width: 100%, --coc-ratio: auto avec une hauteur minimale de 84 px, flèches natives masquées par la CSS de la scène (::scroll-button { display:none }), pastilles conservées.

Comment ça marche

Tout repose sur le défilement du navigateur. La rangée .coc-carousel est un conteneur flex qui défile horizontalement (overflow-x: auto) avec aimantation (scroll-snap-type: x mandatory) : chaque .coc-slide fait 78 % de la largeur et s'arrête centrée. On la fait avancer au doigt, au trackpad, avec Maj + molette, ou avec ← et → quand elle a le focus (elle porte tabindex="0").

Dans Chrome et Edge 135 et plus, le CSS ajoute ce que le navigateur sait désormais générer seul : deux flèches ::scroll-button(left) / ::scroll-button(right) qui défilent d'une page et se grisent en bout de course, et une pastille ::scroll-marker par diapositive, regroupées sous la rangée (scroll-marker-group: after) ; la pastille de la diapositive visible passe en vert d'eau grâce à :target-current. Firefox et Safari ne connaissent pas encore ces pseudo-éléments : ni flèches ni pastilles, mais une fine barre de défilement reste visible pour la souris (elle n'est masquée que là où les pastilles existent, via @supports selector(::scroll-marker)).

La rangée prend la largeur de son conteneur, jusqu'à 640 px par défaut. Chaque diapositive accepte une <img> qui la couvre entièrement ; sans image, le dégradé de la variable --g s'affiche. Comme il n'y a pas de script, plusieurs carrousels sur une page sont indépendants d'office.

Accessibilité

  • Rôles : la rangée est une région aria-roledescription="carrousel" nommée, chaque diapositive un role="group" « 1 sur 5 ». Chrome reprend ces noms pour les pastilles, exposées comme des onglets (« 1 sur 5, onglet »).
  • Flèches nommées : le texte de remplacement de content (content: "‹" / "Précédent") donne aux flèches natives le nom « Précédent » / « Suivant » ; à traduire dans le CSS de la version anglaise.
  • Clavier partout : Tab amène le focus sur la rangée (contour vert d'eau), puis ← → défilent d'une diapositive. Dans Chrome 135+, flèches et pastilles sont aussi atteignables au Tab.
  • Mouvement réduit : sous prefers-reduced-motion: reduce, le défilement doux (scroll-behavior: smooth) est coupé : les flèches et les pastilles amènent la diapositive d'un coup.
  • Toucher : défilement natif, donc le geste vertical fait toujours défiler la page et l'inertie est celle du système.

Compatibilité navigateur

Socle : scroll-snap-type (Chrome 69, Firefox 99, Safari 11) et aspect-ratio (Chrome 88, Firefox 89, Safari 15). Flèches et pastilles : ::scroll-button, ::scroll-marker, scroll-marker-group et :target-current n'existent que dans Chrome et Edge 135+ ; Firefox et Safari ne les ont pas (@mdn/browser-compat-data 8.1.8). Mesuré dans Chromium 151 (flèches, pastilles, noms lus, clic sur une pastille), Firefox 153 et WebKit 26.5 (défilement au clavier, pas d'erreur, rangée à pleine largeur dans une zone de 800 px).

Chrome 135+✓ Complet, flèches et pastilles (mesuré)
Edge 135+✓ Complet (moteur Chromium)
Firefox 99+✓ Défilement aimanté sans flèches ni pastilles (mesuré)
Safari 15+✓ Défilement aimanté sans flèches ni pastilles (mesuré dans WebKit)
Mobile iOS 15+✓ Glisser au doigt, sans pastilles ; non vérifié sur appareil
Android Chrome 135+✓ Complet, flèches et pastilles

Avant Chrome 135 et dans Firefox et Safari : une rangée qui défile au doigt, au trackpad, à la molette avec Maj et au clavier, avec une barre de défilement fine. Si vos visiteurs ont surtout une souris sans molette horizontale, ajoutez vos propres liens ou boutons de navigation.

Le code

Copiez les deux blocs (HTML et CSS) dans votre page. Aucun JavaScript, aucune dépendance.

HTML
<div class="fx-0798-root">
  <div class="coc-wrap">
    <div class="coc-carousel" tabindex="0" role="region" aria-roledescription="carrousel" aria-label="Carrousel">
      <div class="coc-slide" role="group" aria-roledescription="diapositive" aria-label="1 sur 5" style="--g:linear-gradient(135deg,#6d8bff,#5cffd8)">01</div>
      <div class="coc-slide" role="group" aria-roledescription="diapositive" aria-label="2 sur 5" style="--g:linear-gradient(135deg,#ff7eb6,#a777ff)">02</div>
      <div class="coc-slide" role="group" aria-roledescription="diapositive" aria-label="3 sur 5" style="--g:linear-gradient(135deg,#ffb86b,#ff5e8a)">03</div>
      <div class="coc-slide" role="group" aria-roledescription="diapositive" aria-label="4 sur 5" style="--g:linear-gradient(135deg,#4dd2ff,#9b8cff)">04</div>
      <div class="coc-slide" role="group" aria-roledescription="diapositive" aria-label="5 sur 5" style="--g:linear-gradient(135deg,#5cffd8,#3ad6b3)">05</div>
    </div>
  </div>
</div>
CSS
.fx-0798-root,
.fx-0798-root *,
.fx-0798-root *::before,
.fx-0798-root *::after {
  box-sizing: border-box
}

.fx-0798-root {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 250px;
  padding: 20px 0;
  overflow: hidden;
  position: relative;
  background: rgb(26, 26, 36);
  color: rgb(255, 255, 255);
  font-family: sans-serif;
}

/* Largeur : celle du conteneur, plafonnée par --coc-max-width */
.coc-wrap {
  position: relative;
  width: 100%;
  max-width: var(--coc-max-width, 640px);
}

.coc-carousel {
  display: flex;
  gap: 14px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  padding: 6px;
  border-radius: 14px;
  scroll-marker-group: after;
  /* Repli (Firefox, Safari) : fine barre de défilement visible pour la souris */
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, .35) transparent;
}

.coc-carousel:focus-visible {
  outline: 2px solid #5cffd8;
  outline-offset: 2px;
}

.coc-slide {
  position: relative;
  overflow: hidden;
  flex: 0 0 var(--coc-slide-width, 78%);
  scroll-snap-align: center;
  aspect-ratio: var(--coc-ratio, 16 / 9);
  border-radius: 14px;
  display: grid;
  place-items: center;
  color: #fff;
  font-weight: 800;
  font-size: 20px;
  letter-spacing: -0.01em;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.3);
  background: var(--g, linear-gradient(135deg, #6d8bff, #5cffd8));
}

/* Une <img> posée dans une diapositive la couvre entièrement */
.coc-slide > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Flèches et pastilles natives : Chrome / Edge 135+ ; la barre de défilement n'y est plus utile */
@supports selector(::scroll-marker) {
  .coc-carousel {
    scrollbar-width: none;
  }
  .coc-carousel::-webkit-scrollbar {
    height: 0;
  }
}

.coc-slide::scroll-marker {
  content: "";
  width: 9px;
  height: 9px;
  margin: 0 4px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.28);
  cursor: pointer;
  transition: background .2s, transform .2s;
}

.coc-slide::scroll-marker:target-current {
  background: #5cffd8;
  transform: scale(1.3);
}

.coc-slide::scroll-marker:hover {
  background: rgba(255, 255, 255, 0.6);
}

.coc-slide::scroll-marker:focus-visible {
  outline: 2px solid #5cffd8;
  outline-offset: 2px;
}

.coc-carousel::scroll-marker-group {
  display: flex;
  justify-content: center;
  align-items: center;
  padding-top: 12px;
}

.coc-carousel::scroll-button(left),
.coc-carousel::scroll-button(right) {
  position: absolute;
  top: calc(50% - 28px);
  transform: translateY(-50%);
  z-index: 3;
  width: 38px;
  height: 38px;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  font-size: 18px;
  background: rgba(10, 14, 31, 0.65);
  color: #fff;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

.coc-carousel::scroll-button(left) {
  left: 10px;
  content: "‹" / "Précédent";
}

.coc-carousel::scroll-button(right) {
  right: 10px;
  content: "›" / "Suivant";
}

.coc-carousel::scroll-button(left):disabled,
.coc-carousel::scroll-button(right):disabled {
  opacity: .35;
  cursor: default;
}

.coc-carousel::scroll-button(left):focus-visible,
.coc-carousel::scroll-button(right):focus-visible {
  outline: 2px solid #5cffd8;
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .coc-carousel {
    scroll-behavior: auto;
  }
}
JavaScript

CSS pur — aucun JavaScript requis.

Personnaliser

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

Option / propriétéDéfautEffet
Largeur maximale (CSS — --coc-max-width) 640px La rangée prend la largeur de son conteneur jusqu'à cette limite ; none pour toute la largeur.
Largeur d'une diapositive (CSS — --coc-slide-width) 78% 100 % pour une diapositive par vue ; moins de 50 % pour en voir plusieurs.
Proportions (CSS — --coc-ratio) 16 / 9 Rapport largeur/hauteur des diapositives ; auto si vous leur donnez une hauteur.
Fond d'une diapositive (HTML — style="--g: …") linear-gradient(135deg,#6d8bff,#5cffd8) Dégradé ou couleur de chaque diapositive ; une <img> posée dedans la recouvre.
Pastille active (CSS — ::scroll-marker:target-current) #5cffd8, échelle 1,3 Couleur de la pastille de la diapositive visible (Chrome / Edge 135+).
Noms des flèches (CSS — content: "‹" / "Précédent") « Précédent » / « Suivant » Texte lu par les lecteurs d'écran pour les flèches natives ; traduisez-le dans votre CSS.

FAQ

Pourquoi je ne vois ni flèches ni pastilles ?

Vous êtes sur Firefox, Safari ou un Chrome antérieur à la version 135 : ces navigateurs ne génèrent pas encore ::scroll-button et ::scroll-marker. La rangée reste utilisable au doigt, au trackpad, au clavier et avec la barre de défilement.

Comment centrer la première diapositive au chargement ?

L'aimantation centre les diapositives, mais la première ne peut pas être centrée puisqu'il n'y a rien à sa gauche. Ajoutez un padding-inline de 11 % (la moitié de l'espace libre) sur .coc-carousel pour qu'elle démarre au milieu.

Puis-je faire défiler les diapositives toutes seules ?

Pas sans JavaScript : ce carrousel ne bouge que lorsqu'on le fait défiler. C'est aussi ce qui le rend reposant : aucune animation imposée, rien à mettre en pause.