Slider - Comment créer un Slider plein écran ?

Par : TutorialsGrey, le 28 Octobre 2022

Un slider est surtout utilisé pour présenter du contenu comme des images, des projets dans votre portfolio ou même des témoignages de clients. Il est utile parce que vous avez ce contenu concentré dans un écran qui change à un certain moment, comme toutes les 5 secondes, et met en évidence le prochain élément de votre vitrine.

Dans cet article, nous allons créer un Sliderplein écran.

 

Les ressources

La première chose à faire est d'obtenir les images qui seront utilisées dans le slider. Pour cela, Unsplash est l'endroit idéal ! Il propose de magnifiques photos gratuites qui peuvent être utilisées dans n'importe quel projet !

Ensuite, nous avons besoin des icônes pour les boutons de navigation. J'ai choisi d'utiliser FontAwesome.

 

Le HTML

Nous allons tout mettre dans un div principal ".slider", et par tout, j'entends les éléments suivants :

  • un div ".slider-container" qui contiendra tous les ".slide" avec les images (la classe sera utilisée en JavaScript pour obtenir tous les enfants ".slide" de ce div)
  • un div ".eraser" qui sera utilisé pour l'animation d'effacement. En fait, il s'agit de masquer lentement l'élément actuel dans le curseur, et lorsqu'il atteint la fin, nous le remplaçons rapidement par le prochain ".slide".
  • ".buttons-container" qui contient les deux boutons de navigation et deux icônes FontAwesome.
<div class="slider">
    <div class="slider-container">
        <!-- See bellow for the content of this div -->
    </div>
    <div class="eraser"></div>
    <div class="buttons-container">
        <button id="previous"><i class="fa fa-arrow-left"></i></button>
        <button id="next"><i class="fa fa-arrow-right"></i></button>
    </div>
</div>

Maintenant, pour les ".slides"...

Nous plaçons l'image directement dans le style prop de la <div>. En effet, je ne veux pas avoir dans le CSS plusieurs déclarations pour chaque ".slide" séparément, juste pour ajouter une propriété background-image. C'est également utile si, à l'avenir, nous voulons convertir ce slider et faire en sorte que les ".slide" soient ajoutés dynamiquement en utilisant React ou Vue ou autre.

Aussi, nous ajoutons une div (".info") à l'intérieur qui aura un texte supplémentaire que nous voulons afficher au-dessus de l'image. Ceci est facultatif, vous pouvez le supprimer si vous le souhaitez.

<div class="slider">
    <div class="slider-container">
        <div
            class="slide active"
            style="background-image: url('add_image_url_here');"
        >
            <div class="info">
                <h1>Ocean View</h1>
                <p>
                    Lorem ipsum dolor sit amet consectetur adipisicing elit.
                    Voluptatum.
                </p>
            </div>
        </div>
        <div class="slide" style="background-image: url('add_image_url_here');">
            <div class="info">
                <h1>Forest View</h1>
                <p>
                    Lorem, ipsum dolor sit amet consectetur adipisicing elit.
                    Amet, vero earum perspiciatis officia
                </p>
            </div>
        </div>
        <div class="slide" style="background-image: url('add_image_url_here');">
            <div class="info">
                <h1>Ocean View</h1>
                <p>
                    Lorem ipsum dolor sit amet consectetur adipisicing elit.
                    Incidunt recusandae unde autem
                </p>
            </div>
        </div>
        <!-- The rest of the slides -->
    </div>
    <!-- The rest of the content -->
</div>

 

Important

La première diapositive est dotée d'une classe ".active". Nous l'utiliserons plus tard pour suivre dans le JavaScript quel ".slide" est visible/actif à un moment donné.

Notez que le script ne fonctionnera pas si

  • vous avez plusieurs diapositives avec une classe ".active" ou
  • vous n'avez pas de diapositive avec une classe ".active".

 

Le CSS

Comme nous voulons que le Slider soit en plein écran, nous devons soit utiliser le CSS normalisé, soit effectuer quelques réinitialisations simples dans le CSS.

@import url('https://fonts.googleapis.com/css?family=Lato');

* {
    box-sizing: border-box;
}

body {
    font-family: 'Lato', sans-serif;
    margin: 0;
}

(J'ai aussi ajouté la police Lato car j'ai décidé d'ajouter du texte dans le Slider. Vous pouvez supprimer l'importation si vous n'avez pas de texte ou vous pouvez ajouter votre propre police à la balise body).

Les diapositives devront être positionnées de manière absolue si nous voulons les déplacer, ce qui signifie que nous devrons avoir un parent positionné de manière relative, c'est-à-dire la division ".slider".

.slider {
    position: relative;
    overflow: hidden;
    height: 100vh;
    width: 100vw;
}

.slide {
    background-position: center center;
    background-size: cover;
    position: absolute;
    top: 0;
    left: 100%;
    height: 100%;
    width: 100%;
}

.slide.active {
    transform: translateX(-100%);
}

Quelques points à noter ici :

  • 100vh et 100vw signifie que le ".slider" doit être aussi large que l'écran (vh - hauteur du viewport, vw - largeur du viewport).
  • initialement, le ".slider" est positionné à l'extérieur du viewport avec la propriété left définie à 100%, et nous le ramènerons à 0 lorsque la classe ".active" lui sera appliquée (left : 100% + translateX(-100%) = left : 0).

Le code suivant est facultatif. Ne l'utilisez que si vous souhaitez que le texte soit placé au-dessus du ".slide" :

.slide .info {
    background-color: rgba(255, 255, 255, 0.7);
    color: #333;
    padding: 20px 15px;
    position: absolute;
    opacity: 0;
    top: 70px;
    left: 30px;
    text-align: center;
    width: 300px;
    max-width: 100%;
}

.slide.active .info {
    opacity: 1;
    transform: translateY(-40px);
    transition: all 0.5s ease-in-out 0.6s;
}

.slide .info h1 {
    margin: 10px 0;
}

.slide .info p {
    letter-spacing: 1px;
}

Il y a une transition qui ajoutera l'effet de mouvement vers le haut à la div .info et qui changera aussi l'opacité. Il y a aussi un retard à la transition de 0.6s - c'est suffisant pour attendre jusqu'à ce que la classe ".eraser" s'écarte du chemin pour que la transition du texte soit visible.

A ce propos... La classe ".eraser" CSS :

.eraser {
    background: #fff;
    position: absolute;
    transition: transform 0.7s ease-in-out;
    top: 0;
    left: 100%;
    height: 100%;
    width: 100%;
    z-index: 100;
}

.eraser.active {
    transform: translateX(-100%);
}

La classe ".eraser" est un autre div pleine hauteur/largeur qui possède sa propre classe ".active" (à ne pas confondre avec la classe active du ".slide"). Cette classe sera ajoutée en JavaScript lorsque nous voudrons changer la diapositive. Nous y reviendrons un peu plus tard.

Remarque : la valeur de 0,7s est importante car elle devra être exactement la même que celle de l'"eraserActiveTime" utilisée dans le JavaScript.

Et la dernière partie du CSS, le ".buttons-container" :

.buttons-container {
    position: absolute;
    bottom: 60px;
    right: 20px;
}

.buttons-container button {
    border: 2px solid #fff;
    background-color: transparent;
    color: #fff;
    cursor: pointer;
    padding: 8px 20px;
}

.buttons-container button:hover {
    background-color: #fff;
    color: #333;
}

Simple CSS, rien d'extraordinaire ici. Nous positionnons simplement ce div en absolu pour pouvoir le placer où nous voulons dans le ".slider".

 

Le JavaScript

C'est dans cette partie que la magie opère. Tout d'abord, nous devons définir toutes les variables que nous allons utiliser (j'ai ajouté des commentaires pour toutes les lignes, cela devrait être assez clair) :

const slides = document.querySelectorAll('.slider-container .slide'); // get all the slides
const eraser = document.querySelector('.eraser'); // the eraser
const prev = document.getElementById('previous'); // previous button
const next = document.getElementById('next'); // next button
const intervalTime = 5000; // time until nextSlide triggers in miliseconds
const eraserActiveTime = 700; // time to wait until the .eraser goes all the way
let sliderInterval; // variable used to save the setInterval and clear it when needed

Ensuite, nous devons créer une fonction nextSlide qui sera appelée toutes les 5 secondes - l'intervalTime. Décomposons cette fonction en plusieurs étapes :

  • Ajouter la classe ".active" à "eraser" - cela déclenchera le déplacement de "eraser" vers la gauche.
  • Définissez un délai d'attente qui permettra à "eraser" de se déplacer entièrement vers la gauche. C'est ici que nous utiliserons l'eraserActiveTime - il doit être identique à la valeur CSS mentionnée ci-dessus.
  • Trouvez le ".slide" actif et faites basculer la classe ".active" sur celui-ci (dans ce cas, supprimez-la).
  • Vérifiez si le ".slide" a un élément frère suivant disponible. Si c'est le cas, ajoutez-lui la classe ".active".
  • S'il s'agit du dernier élément de la liste, ajoutez la classe ".active" à la première diapositive (celle qui a l'indice 0).
  • Retirez la classe ".active" de "eraser" - cela déclenchera le déplacement de "eraser" vers la droite. Elle attend également 200 ms avant de le faire (afin de laisser suffisamment de temps à la prochaine diapositive pour se mettre en place).
const nextSlide = () => {
    // Step 1.
    eraser.classList.add('active');

    // Step 2.
    setTimeout(() => {
        // Step 3.
        const active = document.querySelector('.slide.active');
        active.classList.toggle('active');

        // Step 4.
        if (active.nextElementSibling) {
            active.nextElementSibling.classList.toggle('active');
        } else {
            // Step 5.
            slides[0].classList.toggle('active');
        }

        // Step 6.
        setTimeout(() => {
            eraser.classList.remove('active');
        }, 200);
    }, eraserActiveTime);
};

sliderInterval = setInterval(nextSlide, intervalTime);

À la fin, nous définissons un intervalle qui sera exécuté toutes les milisecondes intervalTime et qui fera passer la diapositive à la suivante, encore et encore.

 

La fonctionnalité des boutons

Pour l'instant, nous disposons d'un curseur qui change automatiquement de diapositives toutes les milisecondes de l'intervalleTime, mais nous voulons également pouvoir modifier les diapositives manuellement en appuyant sur les boutons. Mais avant cela, ajoutons rapidement la fonction prevSlide. Elle est très similaire à la fonction nextSlide, mais au lieu d'aller à la diapositive suivante, nous allons à la diapositive précédente et lorsque nous réinitialisons, nous définissons la dernière diapositive comme étant active :

const prevSlide = () => {
    eraser.classList.add('active');
    setTimeout(() => {
        const active = document.querySelector('.slide.active');
        active.classList.toggle('active');

        // The *changed* part from the nextSlide code
        if (active.previousElementSibling) {
            active.previousElementSibling.classList.toggle('active');
        } else {
            slides[slides.length - 1].classList.toggle('active');
        }
        // End of the changed part

        setTimeout(() => {
            eraser.classList.remove('active');
        }, 200);
    }, eraserActiveTime);
};

Bien, nous avons les fonctions en place. Tout ce qu'il nous reste à faire est d'ajouter les eventListeners aux boutons :

next.addEventListener('click', () => {
    nextSlide();
    clearInterval(sliderInterval);
    sliderInterval = setInterval(nextSlide, intervalTime);
});

prev.addEventListener('click', () => {
    prevSlide();
    clearInterval(sliderInterval);
    sliderInterval = setInterval(nextSlide, intervalTime);
});

C'est là que nous devons également réinitialiser l'intervalle car nous ne voulons pas qu'il fonctionne pendant que nous appuyons sur les boutons. Pour cela, nous effaçons l'"ancien" intervalle et en créons un nouveau.

Eeeeeet..... nous avons terminé !

 

Conclusion

Félicitations pour être arrivé jusqu'ici ! J'espère que vous avez aimé cet exemple de slider et j'ai hâte de voir ce que vous allez construire ensuite !