Alexandre Buleté - image d'horloge
5 min 3 junio 2022

Construir un slider de imágenes en menos de 2 minutos

Probablemente uno de los elementos más esenciales de la web: ¡slider! ¿Eres principiante y no sabes cómo construir uno? ¿Eres un desarrollador experimentado pero quieres encontrar una solución más rápida desde cero?

En ese caso, lea este artículo que le puede ser útil 😉

Todo lo que necesitamos es un poco de CSS y una pizca de Javascript (vainilla, por supuesto).

Antes de comenzar, un pequeño paréntesis, en este artículo presentaré la lista de imágenes y dots en un loop PHP y el CSS será en forma de SCSS.

Primera etapa: construir la estructura del slider.

1/ Implementación de 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>

Aquí comenzamos por establecer un div.image-slider donde se añaden 2 elementos:

  • la etiqueta div.slider--container que contendrá nuestras arrows (para pasar las imágenes siguientes y precedentes) y la lista de imágenes.
  • la etiquetaul.dots que, como su nombre indica, será nuestra lista de puntos (bajo el slider) que también nos permitirá pasar de una imagen a otra.

También notará el atributo de style left: 0% para el.slider--content. Tenlo bien en cuenta porque es un punto importante en la construcción de nuestro guión.

Una vez el HTML implementado vamos a aplicar el estilo.

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;
            }
        }
    }
}

En este css le flex-shrink: 0 no es necesario en un elemento img pero lo necesitarás si, por ejemplo, encapsulas tus imágenes en un div, esto permitirá que el slider salga de la página y de la ventana y no se restrinja a su contenido.

3/ El 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')
}

En primer lugar, definimos el conjunto de sliders en un querySelectorAll() y luego comprobamos si hay al menos uno en la página (para evitar errores en la consola).

Luego para cada slider encontrado hacemos nuestra animación.

La posición se recupera en el atributo "position" de nuestro .slider--content que inicialmente es "1".

A continuación, comparamos esta posición haciendo clic en las flechas de desplazamiento para comprobar que no estamos sobrepasando los límites de visualización de nuestro slider.

Una vez que esta condición es válida, modificamos el estilo left (mencionado anteriormente) para que el contenido del slider se desplace.

Luego asignamos el nuevo valor de posición a nuestro elemento y llamamos a la function setDots() que nos permite estilizar el punto en la nueva posición.