Un carrousel d’images réalisé uniquement avec CSS3 offre une solution légère et performante par rapport à une implémentation JavaScript. Cette approche repose sur deux mécanismes princip : un agencement HTML structuré et des animations @keyframes pour gérer le défilement automatique. Notez que ce type de carrousel ne permet pas de navigation manuelle, mais s’avère idéal pour des présentations en boucle.
<div class="carousel-wrapper">
<div class="header">
<h1>Carrousel CSS3</h1>
</div>
<div class="carousel-viewport">
<ul class="slides-list">
<li class="slide-item s1">
<a href="#">
<img src="images/photo-1.jpg" alt="Nature">
<span class="label">Voyage</span>
</a>
</li>
<li class="slide-item s2">
<a href="#">
<img src="images/photo-2.jpg" alt="Urban">
<span class="label">Ville</span>
</a>
</li>
<li class="slide-item s3">
<a href="#">
&img src="images/photo-3.jpg" alt="Abstract">
<span class="label">Art</span>
</a>
</li>
<li class="slide-item s4">
<a href="#">
&img src="images/photo-4.jpg" alt="Food">
<span class="label">Gastronomie</span>
</a>
</li>
<li class="slide-item s5">
<a href="#">
&img src="images/photo-5.jpg" alt="Tech">
<span class="label">Technologie</span>
</a>
</li>
</ul>
<div class="progress-indicator"></div>
</div>
</div>
Les images sont empilées en position: absolute à l’intérieur d’un conteneur masquant le débordement (overflow: hidden).
/* Reset minimal */
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul {
list-style: none;
}
/* Conteneur principal */
body {
background: url('./img/pattern.png') repeat;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.carousel-wrapper {
width: 900px;
background: #fff;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
padding: 20px;
}
.header {
text-align: center;
padding: 20px 0;
font-size: 1.5rem;
color: #333;
}
/* Vue du carrousel */
.carousel-viewport {
position: relative;
width: 100%;
max-width: 800px;
height: 500px;
margin: 0 auto;
border: 4px solid #ddd;
overflow: hidden;
border-radius: 8px;
}
.slides-list {
position: relative;
width: 100%;
height: 100%;
}
.slide-item {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: pointer;
background: #fff;
}
.slide-item img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.label {
position: absolute;
bottom: 20px;
left: 30px;
background: rgba(0,0,0,0.65);
color: #fff;
padding: 10px 20px;
border-radius: 6px;
opacity: 0;
transform: translateY(10px);
transition: 0.3s ease;
}
.slide-item:hover .label {
opacity: 1;
transform: translateY(0);
}
Le cycle total dure 25 secondes pour 5 slides (5 secondes par slide). Chaque animation déplace la diapositive de la position visible (left:0) vers la droite (left: 800px) puis la repositionne instantanément à gauche (left: -800px) en attendant le prochain tour. Les z-index sont ajustés pour que seule la diapositive active reste visible quand elle est dans la zone.
Première diapositive (.s1)
.slide-item.s1 {
animation: anim1 25s linear infinite;
}
@keyframes anim1 {
0% { left: 0; opacity: 1; z-index: 2; }
16% { left: 0; opacity: 1; z-index: 2; }
20% { left: 800px; opacity: 0; z-index: 1; }
21% { left: -800px; opacity: 0; z-index: 0; }
95% { left: -800px; opacity: 0; z-index: 1; }
100% { left: 0; opacity: 1; z-index: 2; }
}
Deuxième diapositive (.s2)
.slide-item.s2 {
animation: anim2 25s linear infinite;
}
@keyframes anim2 {
0% { left: -800px; opacity: 0; z-index: 0; }
16% { left: -800px; opacity: 0; z-index: 1; }
20% { left: 0; opacity: 1; z-index: 2; }
36% { left: 0; opacity: 1; z-index: 2; }
40% { left: 800px; opacity: 0; z-index: 1; }
41% { left: -800px; opacity: 0; z-index: 0; }
100% { left: -800px; opacity: 0; z-index: 0; }
}
Les trois autres dipaositives suivent la même logique avec des décalages de 5 secondes chacun (20%, 36%, 52%, etc.).
Une barre horizontale située en bas du carrousel indique le temps restant avant le changement de slide. Son animation dure 5 secondes (80% du cycle de chaque slide).
.progress-indicator {
position: absolute;
bottom: 0;
left: 0;
height: 6px;
background: rgba(0,0,0,0.6);
width: 0;
border-radius: 0 0 6px 6px;
animation: progressAnim 5s linear infinite;
z-index: 10;
}
@keyframes progressAnim {
0% { width: 0; }
80% { width: 100%; }
81% { width: 0; }
100% { width: 0; }
}
Pour une meilleure expérience, le défilement peut être suspendu lorsque l’utilisateur passe la souris sur le carrousel.
.carousel-viewport:hover .slide-item,
.carousel-viewport:hover .progress-indicator {
animation-play-state: paused;
}