Création d'un Carrousel d'Images Interactif avec CSS Pur

Initialisation de l'environnement

Pour commencer, nous réinitialisons les marges par défaut et configurons le conteneur principal avec Flexbox pour centrer notre composant au milieu de la fenêtre d'affichage.

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: #a4cae0;
}

Structure HTML du Carrousel

La mécanique repose sur l'utilisation de boutons radio masqués associés à des balises <label>. Cliquer sur un label sélectionne le radio correspondant, ce qui permet au CSS de réagir via la pseudo-classe :checked. Le sélecteur de voisin général ~ est ensuite utilisé pour cibler les diapositives et les indicateurs situés après l'input sélectionné dans le flux du document.

<div class="carousel-wrapper">
    <!-- Contrôles radio masqués -->
    <input type="radio" name="slide-nav" id="rd1" checked>
    <input type="radio" name="slide-nav" id="rd2">
    <input type="radio" name="slide-nav" id="rd3">

    <!-- Diapositives -->
    <div class="slide panel-a"></div>
    <div class="slide panel-b"></div>
    <div class="slide panel-c"></div>

    <!-- Navigation -->
    <div class="nav-dots">
        <label for="rd1"></label>
        <label for="rd2"></label>
        <label for="rd3"></label>
    </div>
</div>

Styles de Base et Positionnement

Le conteneur principal nécessite un positionnement relatif et la propriété overflow: hidden pour masquer les diapositives qui débordent. Les diapositives sont positionnées de manière absolue et se voient attribuer une transition fluide pour animer le glissement.

.carousel-wrapper {
    position: relative;
    width: 500px;
    height: 300px;
    overflow: hidden;
    border-radius: 8px;
}

.slide {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    transition: transform 0.6s ease-in-out;
    background-size: cover;
    background-position: center;
}

/* Masquage des inputs radio */
input[type="radio"] {
    display: none;
}

Agencement Initial des Diapositives

Chaque image de fond est assignée à un panneau. Par défaut, la première est visible (positionnée à gauche: 0). Les suivantes sont décalées de 100% et 200% vers la droite pour s'aligner côte à côte en dehors de la zone visible du conteneur.

.panel-a { background-image: url('img/photo1.jpg'); }
.panel-b { background-image: url('img/photo2.jpg'); left: 100%; }
.panel-c { background-image: url('img/photo3.jpg'); left: 200%; }

Indicateurs de Navigation

Les indicateurs de position (points) sont placés en bas au centre du carrousel en combinant left: 50% et transform: translateX(-50%). Flexbox permet de les répartir uniformément.

.nav-dots {
    position: absolute;
    bottom: 15px;
    left: 50%;
    transform: translateX(-50%);
    width: 70px;
    height: 15px;
    z-index: 10;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.nav-dots label {
    width: 12px;
    height: 12px;
    background-color: #ffffff;
    border-radius: 50%;
    cursor: pointer;
    border: 2px solid #ffffff;
}

Logique de Défilement et Rétroaction Visuelle

Lorsqu'un radio est coché, nous utilisons le sélecteur ~ pour cibler l'indicateur correspondant via son attribut for et modifier son aparence (fond sombre). Simultanément, nous appliquons une translation horizontale à l'ensemble des éléments .slide pour afficher la diapositive associée au bouton actif.

/* Style actif des indicateurs */
.carousel-wrapper #rd1:checked ~ .nav-dots label[for="rd1"],
.carousel-wrapper #rd2:checked ~ .nav-dots label[for="rd2"],
.carousel-wrapper #rd3:checked ~ .nav-dots label[for="rd3"] {
    background-color: #1a1a1a;
}

/* Défilement des diapositives */
.carousel-wrapper #rd1:checked ~ .slide {
    transform: translateX(0);
}
.carousel-wrapper #rd2:checked ~ .slide {
    transform: translateX(-100%);
}
.carousel-wrapper #rd3:checked ~ .slide {
    transform: translateX(-200%);
}

Étiquettes: CSS carrousel flexbox pseudo-classes HTML

Publié le 16 septembre à 05h42