Se rendre au contenu

Welcome .


Sign u

Cette question a été signalée

Voici un carousel HTML/CSS/JS (vanilla, sans librairie) prêt à coller dans votre site web.

Il gère : autoplay, pause au survol, swipe mobile, flèches, puces, clavier, accessibilité ARIA — et tu peux modifier chaque slide très facilement.

✅ Copier-coller tel quel

✅ Personnalisation via attributs data-* et/ou en éditant le contenu des slides

✅ Aucune dépendance externe

<div
id="carousel-1"
class="carousel"
data-autoplay="true" <!-- "false" pour désactiver l’auto -->
data-interval="3500" <!-- délai ms entre slides en auto -->
data-speed="450" <!-- durée de transition ms -->
data-pause-on-hover="true" <!-- pause si souris survole -->
data-loop="true" <!-- boucle infinie -->
data-show-dots="true" <!-- puces sous le slider -->
data-show-arrows="true" <!-- flèches gauche/droite -->
...
<div
id="carousel-1"
class="carousel"
data-autoplay="true" <!-- "false" pour désactiver l’auto -->
data-interval="3500" <!-- délai ms entre slides en auto -->
data-speed="450" <!-- durée de transition ms -->
data-pause-on-hover="true" <!-- pause si souris survole -->
data-loop="true" <!-- boucle infinie -->
data-show-dots="true" <!-- puces sous le slider -->
data-show-arrows="true" <!-- flèches gauche/droite -->
data-keyboard="true" <!-- navigation au clavier -->
data-aspect-ratio="16/9" <!-- ratio (ex: 16/9, 3/1, 1/1) -->
aria-roledescription="carousel"
aria-label="Carousel de mise en avant"
>
<div class="carousel__viewport" aria-live="polite">
<!-- === SLIDE 1 === -->
<section class="carousel__slide" aria-label="Slide 1">
<img class="slide__bg" src="https://picsum.photos/1600/900?random=1" alt="" loading="lazy" />
<div class="slide__content">
<h2>Bienvenue 🎉</h2>
<p>Un texte d’accroche clair et court.</p>
<a class="btn" href="#">Appel à l’action</a>
</div>
</section>

<!-- === SLIDE 2 === -->
<section class="carousel__slide" aria-label="Slide 2">
<img class="slide__bg" src="https://picsum.photos/1600/900?random=2" alt="" loading="lazy" />
<div class="slide__content">
<h2>Produit phare</h2>
<p>Mettez ici votre valeur ajoutée.</p>
<a class="btn" href="#">Découvrir</a>
</div>
</section>

<!-- === SLIDE 3 === -->
<section class="carousel__slide" aria-label="Slide 3">
<img class="slide__bg" src="https://picsum.photos/1600/900?random=3" alt="" loading="lazy" />
<div class="slide__content">
<h2>Événement</h2>
<p>Date, lieu, lien d’inscription.</p>
<a class="btn" href="#">Je participe</a>
</div>
</section>
</div>

<!-- Flèches (générées si data-show-arrows=true, mais on les laisse ici pour fallback) -->
<button class="carousel__arrow prev" aria-label="Slide précédente" data-dir="-1">‹</button>
<button class="carousel__arrow next" aria-label="Slide suivante" data-dir="1">›</button>

<!-- Puces : générées automatiquement (on laisse un conteneur vide) -->
<div class="carousel__dots" role="tablist" aria-label="Choisir la slide"></div>
</div>

<style>
/* --- Layout de base --- */
.carousel {
position: relative;
width: 100%;
overflow: hidden;
border-radius: 16px;
box-shadow: 0 10px 30px rgba(0,0,0,.15);
background: #0b1020;
}
/* Aspect ratio via data-aspect-ratio */
.carousel::before {
content: "";
display: block;
padding-top: calc(100% / (attr(data-aspect-ratio) * 1)); /* fallback ignoré, JS fixe la hauteur */
}
.carousel__viewport {
position: absolute; inset: 0;
display: flex;
will-change: transform;
height: 100%;
}
.carousel__slide {
position: relative;
min-width: 100%;
height: 100%;
display: grid;
place-items: center;
isolation: isolate;
}
.slide__bg {
position: absolute; inset: 0;
width: 100%; height: 100%;
object-fit: cover;
filter: brightness(.8) saturate(1.1);
z-index: -1;
}
.slide__content {
text-align: center;
color: #fff;
padding: 1rem 2rem;
max-width: 900px;
animation: fadeUp .6s ease both;
}
.slide__content h2 { font-size: clamp(1.6rem, 2.8vw, 2.6rem); margin: 0 0 .4rem; }
.slide__content p { font-size: clamp(1rem, 1.4vw, 1.2rem); opacity: .95; margin: 0 0 1rem; }
.btn {
display: inline-block; padding: .7rem 1.1rem; border-radius: 999px;
background: #ffd93b; color: #111; text-decoration: none; font-weight: 600;
}
@keyframes fadeUp { from { opacity: 0; transform: translateY(10px) } to { opacity: 1; transform: translateY(0) } }

/* --- Flèches --- */
.carousel__arrow {
position: absolute; top: 50%; transform: translateY(-50%);
width: 42px; height: 42px; border-radius: 50%;
border: none; background: rgba(255,255,255,.85);
font-size: 26px; line-height: 42px; text-align: center; cursor: pointer;
user-select: none; z-index: 2;
}
.carousel__arrow.prev { left: 10px; }
.carousel__arrow.next { right: 10px; }
.carousel__arrow:focus { outline: 2px solid #111; }

/* --- Puces --- */
.carousel__dots {
position: absolute; left: 0; right: 0; bottom: 10px;
display: flex; gap: 8px; justify-content: center; z-index: 2;
}
.carousel__dot {
width: 10px; height: 10px; border-radius: 50%;
background: rgba(255,255,255,.6); border: none; cursor: pointer;
}
.carousel__dot[aria-selected="true"] { background: #ffd93b; }

/* Accessibilité & préférences */
@media (prefers-reduced-motion: reduce) {
.carousel__viewport, .slide__content { transition: none !important; animation: none !important; }
}
</style>

<script>
(function(){
"use strict";

const root = document.getElementById("carousel-1");
if (!root) return;

const vp = root.querySelector(".carousel__viewport");
const slides = Array.from(root.querySelectorAll(".carousel__slide"));
const dotsWrap = root.querySelector(".carousel__dots");
const btnPrev = root.querySelector(".carousel__arrow.prev");
const btnNext = root.querySelector(".carousel__arrow.next");

// Options via data-*
const opts = {
autoplay: (root.dataset.autoplay || "true") === "true",
interval: Math.max(1000, parseInt(root.dataset.interval || "3500", 10)),
speed: Math.max(60, parseInt(root.dataset.speed || "450", 10)),
pauseOnHover: (root.dataset.pauseOnHover || "true") === "true",
loop: (root.dataset.loop || "true") === "true",
showDots: (root.dataset.showDots || "true") === "true",
showArrows: (root.dataset.showArrows || "true") === "true",
keyboard: (root.dataset.keyboard || "true") === "true",
aspectRatio: root.dataset.aspectRatio || "16/9",
};

// Hauteur via ratio
function applyAspectRatio() {
const [w,h] = opts.aspectRatio.split("/").map(Number);
const ratio = (isFinite(w) && isFinite(h) && h !== 0) ? (h / w) : (9/16);
const width = root.clientWidth || root.getBoundingClientRect().width || 1200;
root.style.height = Math.round(width * ratio) + "px";
}
applyAspectRatio();
new ResizeObserver(applyAspectRatio).observe(root);

let index = 0;
let timer = null;
let isAnimating = false;

// Init styles
vp.style.transition = `transform ${opts.speed}ms ease`;

function goTo(i, {animate=true} = {}) {
if (isAnimating) return;
const total = slides.length;
if (!opts.loop) {
i = Math.max(0, Math.min(i, total - 1));
} else {
if (i < 0) i = total - 1;
if (i >= total) i = 0;
}
isAnimating = true;
if (!animate) vp.style.transition = "none";
vp.style.transform = `translateX(${-i * 100}%)`;
if (!animate) {
// force reflow to re-enable transition proprement
vp.offsetHeight;
vp.style.transition = `transform ${opts.speed}ms ease`;
}
setTimeout(()=>{
index = i;
updateDots();
isAnimating = false;
}, animate ? opts.speed : 0);
}

// Dots
function buildDots() {
if (!opts.showDots || slides.length < 2) { dotsWrap.style.display = "none"; return; }
dotsWrap.innerHTML = "";
slides.forEach((_, i) => {
const b = document.createElement("button");
b.className = "carousel__dot";
b.role = "tab";
b.ariaLabel = `Aller à la slide ${i+1}`;
b.addEventListener("click", () => { stopAuto(); goTo(i); startAuto(); });
dotsWrap.appendChild(b);
});
updateDots();
}
function updateDots() {
const dots = dotsWrap.querySelectorAll(".carousel__dot");
dots.forEach((d, i) => d.setAttribute("aria-selected", i === index ? "true" : "false"));
}

// Arrows
if (!opts.showArrows) {
btnPrev.style.display = "none";
btnNext.style.display = "none";
}
btnPrev.addEventListener("click", () => { stopAuto(); goTo(index - 1); startAuto(); });
btnNext.addEventListener("click", () => { stopAuto(); goTo(index + 1); startAuto(); });

// Keyboard
if (opts.keyboard) {
root.tabIndex = 0;
root.addEventListener("keydown", (e) => {
if (e.key === "ArrowLeft") { e.preventDefault(); stopAuto(); goTo(index - 1); startAuto(); }
if (e.key === "ArrowRight"){ e.preventDefault(); stopAuto(); goTo(index + 1); startAuto(); }
});
}

// Autoplay
function startAuto() {
if (!opts.autoplay || slides.length < 2) return;
stopAuto();
timer = setInterval(() => goTo(index + 1), opts.interval);
}
function stopAuto() { if (timer) { clearInterval(timer); timer = null; } }

if (opts.pauseOnHover) {
root.addEventListener("mouseenter", stopAuto);
root.addEventListener("mouseleave", startAuto);
}

// Swipe (touch)
let startX = 0, deltaX = 0, dragging = false;
root.addEventListener("touchstart", (e)=> {
dragging = true;
startX = e.touches[0].clientX;
deltaX = 0;
stopAuto();
vp.style.transition = "none";
}, {passive:true});
root.addEventListener("touchmove", (e)=> {
if (!dragging) return;
deltaX = e.touches[0].clientX - startX;
vp.style.transform = `translateX(calc(${-index*100}% + ${deltaX}px))`;
}, {passive:true});
root.addEventListener("touchend", ()=> {
if (!dragging) return;
vp.style.transition = `transform ${opts.speed}ms ease`;
dragging = false;
if (Math.abs(deltaX) > root.clientWidth * 0.15) {
goTo(index + (deltaX < 0 ? 1 : -1));
} else {
goTo(index, {animate:true});
}
startAuto();
}, {passive:true});

// Construire les puces et démarrer
buildDots();
// Position initiale sans animation
goTo(0, {animate:false});
startAuto();

// petite API si besoin dans la console
root._carousel = {
next: () => goTo(index + 1),
prev: () => goTo(index - 1),
go: (i) => goTo(i),
start: startAuto,
stop: stopAuto
};
})();
</script>

Comment modifier chaque slide :

  • Image de fond : remplace l’URL dans <img class="slide__bg" src="...">.
    Tu peux aussi enlever l’image et mettre une couleur ou un dégradé en CSS sur .carousel__slide.
  • Titres / textes / bouton : édite le contenu du bloc
<p><div class="slide__content"></p><p>  <h2>Mon titre</h2></p><p>  <p>Mon texte.</p></p><p>  <a class="btn" href="/ma-cible">Mon CTA</a></p><p></div></p><p><div class="slide__content"></p><p>  <h2>Mon titre</h2></p><p>  <p>Mon texte.</p></p><p>  <a class="btn" href="/ma-cible">Mon CTA</a></p><p></div></p>

Ajouter/Supprimer une slide : duplique ou supprime tout le <section class="carousel__slide">…</section>.

Les puces se régénèrent automatiquement.

Changer la vitesse : data-speed="450" (en ms).

Changer l’intervalle d’autoplay : data-interval="3500" (en ms).


Désactiver l’autoplay : data-autoplay="false".


Pause au survol : data-pause-on-hover="true" ou false.


Boucle infinie : data-loop="true" ou false.


Flèches/Puces : data-show-arrows="true" / data-show-dots="true".


Clavier : data-keyboard="true" pour activer ← →.


Ratio d’affichage : data-aspect-ratio="16/9" (exemples : 3/1, 4/3, 1/1).

Le JS ajuste la hauteur automatiquement selon la largeur du bloc

Ignorer

Merci beaucoup parfait 👍🏼 

Publications associées Réponses Vues Activité
0
août 25
3
0
août 25
4
0
août 25
57
0
août 25
57
0
août 25
109