Alexandre Buleté - image d'horloge
5 min 21 août 2021

Construire un slider d’images en moins de 2 minutes

Probablement l’un des éléments les plus incontournables du web : les sliders ! Vous êtes débutant et ne savez pas comment en construire un ? Vous êtes un développeur confirmé mais souhaitez trouver une solution plus rapide et light from scratch ?

Dans ce cas lisez cet article il pourrait vous être utile 😉

Nous aurons simplement besoin d’un peu de CSS et d’une pincée de Javascript (vanilla bien évidemment).

Petite parenthèse, dans cet article je présenterai la liste des images et des dots dans une loop PHP et le CSS sera sous forme de SCSS.

Première étape : construire la structure du slider.

1/ Mettre en place le HTML

<div class="image-slider">
    <div class="slider--container">
        <div class="prev-btn"><</div>
        <div class="next-btn">></div>
        <div class="slider--content" position="1" style="left:0%">
            <?php foreach($imgs as $img): ?>
                <img 
                    src="<?= $img['url'] ?>" 
                    alt="<?= $img['alt'] ?>" 
                >
        </div>
    </div>
    <ul class="dots">
        <?php for($i=0; $i < count($imgs); $i++): ?>
            <li 
                class="dot <?= $i === 0 ? 'current' : '' ?>"
                pos="<?= $i ?>"
            >
            </li>
        <?php endfor; ?>
    </ul>
</div>

Ici on commence par mettre en place une div.image-slider où l’on y ajoute 2 éléments :

  • la balise div.slider--container qui contiendra nos arrows (pour faire passer les images suivantes et précédentes) et la liste d’images.
  • la balise ul.dots qui, comme son nom l’indique, sera notre liste de points (sous le slider) qui nous permettra également de passer d’une image à une autre.

Vous remarquerez aussi l’attribut style avec un left: 0% pour le .slider--content. Retenez-le bien car il s’agit d’un point important dans la construction de notre script.

Une fois le HTML mis en place nous allons y appliquer le style.

2/ Application du style

$grey-20 : #CCC;
$grey-60 : #666;

.image-slider {
    .slider--container {
        position: relative;
        overflow: hidden;
        .slider--content {
            positon: relative;
            display: flex;
            transition: all .4s ease;
            img {
                width: 100%;
                box-sizing: border-box;
                border: 1px solid $grey-20;
                flex-shrink: 0;
            }
        }
        .prev-btn, .next-btn {
            z-index: 1;
            position: absolute;
            top: 0;
            bottom: 0;
            width: 70px;
            display: grid;
            justify-content: center;
            align-content: center;
            font-size: 36px;
            font-weight: 200;
            cursor: pointer;
            background: rgba(white, .5);
            box-shadow: 0 0 15px rgba(black, .1);
            transition: all .4s ease;
        }
        .prev-btn {
            left:-100px;
        }
        .next-btn {
            right:-100px;
        }
        &:hover {
            .prev-btn {
                left:0;
            }
            .next-btn {
                right:0;
            }
        }
    }
    .dots {
        display: flex;
        justify-content: center;
        padding-top: 10px;
        margin-top: 10px;
        .dot {
            cursor: pointer;
            height: 10px;
            width: 10px;
            border: 1px solid $grey-20;
            border-radius: 50px;
            margin: 0 4px;
            box-sizing: border-box;
            &.current {
                background: $grey-60;
            }
        }
    }
}

Dans ce css le flex-shrink: 0 n’est pas nécessaire sur un élément de type img mais vous en aurez besoin si, par exemple, vous encapsulez vos images dans une div, cela permettra au slider de sortir de la page et de la fenêtre et ne pas les restreindre à l’intérieur de leur content.

3/ Le script

let sliderSections = document.querySelectorAll('.image-slider')

if (sliderSections.length) {
    sliderSections.forEach(slider => {
        let imgs = slider.querySelectorAll('img')
        let content = slider.querySelector('.slider--content')
        let pos = content.getAttribute('position')
        let length = imgs.length
        let prevBtn = slider.querySelector('.prev-btn')
        let nextBtn = slider.querySelector('.next-btn')
        let dots = slider.querySelectorAll('.dots .dot')
        nextBtn.addEventListener('click', () => {
            if (pos < length) {
                let res = content.style.left.replace('%', '') - 100
                content.setAttribute('style', `left:${res}%`)
                pos++
                setDots(dots, pos)
                content.setAttribute('position', pos)
            }
        })
        prevBtn.addEventListener('click', () => {
            if (pos > 1) {
                let res = parseInt(content.style.left.replace('%', '')) + 100
                content.setAttribute('style', `left:${res}%`)
                pos--
                setDots(dots, pos)
                content.setAttribute('position', pos)
            }
        })
        dots.forEach( dot => {
            dot.addEventListener('click', () => {
                dot.classList.remove('current')
                let p = dot.getAttribute('pos')
                let res = parseInt(p) * 100
                content.setAttribute('style', `left:-${res}%`)
                p++
                setDots(dots, p)
                content.setAttribute('position', p)
            })
        })
    })
}

function setDots(dots, pos) {
    console.log(pos)
    dots.forEach(dot => {
        dot.classList.remove('current')
    })
    dots[pos - 1].classList.add('current')
}

Dans un premier temps on définit l’ensemble des sliders dans un querySelectorAll() puis on vérifie s’il y en a au moins un sur la page (pour éviter les erreurs dans la console).

Ensuite pour chaque slider trouvé on effectue notre animation.

La position est récupéré dans l’attribute "position" de notre .slider--content qui est initialement "1".

On compare ensuite cette position lors du click sur les flèches de défilement afin de vérifie que l’on ne dépasse pas les limites d’affichage de notre slider.

Une fois cette condition valide on modifie le style left (dont je vous parlais plus tôt) afin de faire défilement le contenu du slider.

Puis on attribue la nouvelle valeur position à notre élément et on appelle la function setDots() qui nous permet de styliser le point de la nouvelle position.