Cómo crear una galería de imágenes atractiva y responsiva con slick.js
Spanish (Español) translation by Carlos (you can also view the original English article)
En este tutorial utilizaremos slick.js, un popular plugin de jQuery, para crear una atractiva galería de imágenes responsiva. Aquí está la galería que vamos a elaborar:
Asegúrate de revisar la versión a pantalla completa y cambiar el tamaño de la ventana de tu navegador para ver cómo cambia su diseño según el tamaño de la ventana.
¿Qué es slick.js?
Slick.js es un conocido plugin de jQuery creado por Ken Wheeler que te permite crear hermosos carruseles responsivos. Para comprender mejor lo que este plugin puede ofrecer, revisa la documentación.
Por fortuna, funciona no solo en todos los navegadores modernos, sino también en algunos más antiguos como IE 8.
Es probable que también quieras echar un vistazo a la versión de WordPress.
Comenzando con slick.js
Para empezar con Slick, descarga e instala los siguientes archivos en tu proyecto:
- jQuery (≥1.7)
-
slick.css
o su versión minimizada
-
slick.js
o su versión minimizada
Opcionalmente, es posible que quieras importar el archivo slick-theme.css
.
Puede consegui una copia de los archivos Slick correspondientes visitando su repositorio Github, utilizando un administrador de paquetes (por ejemplo, npm) o cargando los recursos necesarios a través de un CDN (por ejemplo, cdnjs). Para este tutorial, yo optaré por la última opción.
Asimismo, incorporé a Babel para compilar el código ES6 a ES5 y Lodash para aprovechar su función debounce
(la utilizaremos más adelante).
Con esto en mente, si observas en la pestaña Settings (ajustes) de nuestra demostración, verás que he incluido un archivo CSS externo y tres archivos JavaScript externos.






1. El HTML
En este punto es importante entender la estructura de nuestra página. Lo más importante es que definiremos dos carruseles que tienen exactamente las mismas imágenes y están sincronizados (comentaremos cómo más adelante). Las dimensiones de la imagen son 860 x 550 píxeles, aunque en tus proyectos, estas pueden ser diferentes.
Finalmente, como parte del segundo carrusel, especificaremos las flechas de navegación, así como un elemento que mantiene un seguimiento del número total de diapositivas.
Aquí está la estructura requerida para nuestra página de demostración:
<div class="loading">Carousel is loading...</div> <div class="container"> <div class="synch-carousels"> <div class="left child"> <div class="gallery"> <div class="item"> <img src="IMG_SRC" alt=""> </div> <!-- 4 more images here --> </div> </div><!--/left--> <div class="right child"> <div class="gallery2"> <div class="item"> <img src="IMG_SRC" alt=""> </div> <!-- 4 more images here --> </div> <div class="nav-arrows"> <button class="arrow-left"> <!--svg here--> </button> <button class="arrow-right"> <!--svg here--> </button> </div> <div class="photos-counter"> <span></span><span></span> </div> </div><!--/right--> </div> </div>
2. El CSS
En total, nuestra galería debe tener cuatro aspectos distintos, dependiendo de la ventana disponible. Vamos a visualizarlos siguiendo un enfoque "móviles primero".
Cuando la ventana del navegador tenga menos de 480 píxeles, debería tener este aspecto, con solo el segundo carrusel y la navegación mostrandose:



Luego, en pantallas entre 480px y 768px, debe ser como sigue, con dos miniaturas debajo de la diapositiva principal:



A continuación, en las pantallas entre 769px y 1023px, presentaremos una tercera miniatura:



Por último, en pantallas grandes (≥1024 px), debe ser como sigue, con las miniaturas apareciendo a un lado (nota que no caben completamente en esta imagen en su totalidad):



Todos los casos anteriores se ajustan con los "media queries" que se muestran a continuación:
.synch-carousels { position: relative; display: flex; flex-wrap: wrap; justify-content: space-between; } .synch-carousels > * { width: 100%; } .synch-carousels .right { order: -1; } .synch-carousels .left { overflow: hidden; } .synch-carousels .gallery { display: none; } .synch-carousels .gallery .slick-list { height: auto !important; margin: 0 -20px; } .synch-carousels .gallery .slick-slide { margin: 0 20px; } @media screen and (min-width: 480px) { .synch-carousels .right { margin-bottom: 20px; } .synch-carousels .gallery { display: block; } } @media screen and (min-width: 1024px) { .synch-carousels .right { position: relative; width: calc(100% - 230px); margin-bottom: 0; order: 2; } .synch-carousels .left { width: 210px; } .synch-carousels .gallery .slick-slide { margin: 0 0 20px 0; } .synch-carousels .gallery .slick-list { margin: 0; } }
Observa que hay una regla !important
. Esto sobrescribe un estilo "inline" de Slick.
3. El JavaScript
Ahora vamos a centrar nuestra atención en las cosas relacionadas con JavaScript.
Almacenando selectores en caché
Cuando el DOM está listo, como buena práctica almacenamos en memoria caché algunos selectores de uso común:
const $left = $(".left"); const $gl = $(".gallery"); const $gl2 = $(".gallery2"); const $photosCounterFirstSpan = $(".photos-counter span:nth-child(1)");
Inicializando los carruseles
Luego, inicializamos y sincronizamos nuestros dos carruseles. El código responsable de este comportamiento es el siguiente:
$gl.slick({ rows: 0, slidesToShow: 2, arrows: false, draggable: false, useTransform: false, mobileFirst: true, responsive: [ { breakpoint: 768, settings: { slidesToShow: 3 } }, { breakpoint: 1023, settings: { slidesToShow: 1, vertical: true } } ] }); $gl2.slick({ rows: 0, useTransform: false, prevArrow: ".arrow-left", nextArrow: ".arrow-right", fade: true, asNavFor: $gl });
Sin duda, la mejor manera de comprender cómo funciona este código es leer la documentación de Slick. Sin embargo, déjame explicar dos cosas importantes aquí:
- La opción de configuración
asNavFor
nos permite sincronizar los carruseles y utilizar uno como navegación del otro. - De forma predeterminada, Slick utiliza transformaciones CSS. En nuestro caso, sin embargo, las deshabilitamos configurando
useTransform: false
. Esto es porque causan un pequeño parpadeo en la primera diapositiva del primer carrusel en pantallas grandes (podríamos haberlas desactivado solo para el primer carrusel).
Visualizando y modificando la disposición de la galería
Nuestra galería debe ser visible solo cuando todos los recursos de la página estén listos. Inicialmente, aparece un precargador opcional (consulta el markup de nuevo), se ve así:
<div class="loading">Carousel is loading...</div>
En este punto, tenemos que volver a pensar en la distribución deseada de la galería en pantallas grandes. Si vuelves a mirar las capturas de pantalla correspondientes, notarás que ambos carruseles tienen la misma altura. Para lograr ese comportamiento deseado, tenemos que escribir un código JavaScript personalizado (más allá de nuestro CSS). Este código establecerá dinámicamente la altura del primer carrusel igual a la altura del segundo (o viceversa).
Conociendo los requisitos anteriores, aquí está el código que se ejecuta cuando toda la página está lista:
$(window).on("load", () => { handleCarouselsHeight(); setTimeout(() => { $(".loading").fadeOut(); $("body").addClass("over-visible"); }, 300); });
Y aquí está la declaración de la función handleCarouselsHeight
:
function handleCarouselsHeight() { if (window.matchMedia("(min-width: 1024px)").matches) { const gl2H = $(".gallery2)").height(); $left.css("height", gl2H); } else { $left.css("height", "auto"); } }
Cuando la página se carga, la galería funciona bien. Pero también debería funcionar como se esperaba cuando la ventana del navegador cambie de tamaño.
El código que afronta esa situación se muestra a continuación:
$(window).on( "resize", _.debounce(() => { handleCarouselsHeight(); }, 200) );
Observa que el controlador de eventos está envuelto dentro de una función debounce
. Esta es una función de Lodash que nos ayuda a restringir la cantidad de veces que se llama este controlador.
Trabajando con los eventos y métodos de Slick
Ahora que hemos implementado con éxito la funcionalidad principal de nuestra galería, vamos a ir un paso más allá y crearemos algunas cosas opcionales.
Primero, en la esquina superior derecha del segundo carrusel, mostramos la diapositiva actual y el número total de diapositivas.



Para lograr esto, aprovechamos los eventos de Slick init
y afterChange
.
Aquí está el código relacionado:
/*you have to bind init event before slick's initialization (see demo) */ gl2.on("init", (event, slick) => { $photosCounterFirstSpan.text(`${slick.currentSlide + 1}/`); $(".photos-counter span:nth-child(2)").text(slick.slideCount); }); $gl2.on("afterChange", (event, slick, currentSlide) => { $photosCounterFirstSpan.text(`${slick.currentSlide + 1}/`); });
Como una mejora adicional, cada vez que hagamos clic en una diapositiva del primer carrusel, la diapositiva asociada del segundo carrusel debe estar activa. Gracias al método slickGoTo
de Slick, podemos desarrollar esta funcionalidad.
Aquí está el código relacionado:
$(".gallery .item").on("click", function() { const index = $(this).attr("data-slick-index"); $gl2.slick("slickGoTo", index); });
4. Soporte en navegadores
La demostración debería funcionar bien en todos los navegadores recientes y puedes utilizarla de forma segura en tus proyectos.
Solamente he encontrado un pequeño error en algunos navegadores (Firefox, Edge) al probar la demostración en pantallas grandes. Al hacer clic en las flechas de navegación, todas las diapositivas del primer carrusel, aparte del primero, fallan para alcanzar el borde superior y dejan un espacio de un solo píxel:



Y en último lugar, aunque no menos importante, es posible que se necesiten pequeñas mejoras y modificaciones a medida que la ventana cambie de tamaño, dependiendo de tus necesidades.
Conclusión
En este tutorial, aprovechamos slick.js y logramos construir una hermosa galería con capacidad responsiva. Esperemos que ahora estés listo para probar esta implementación en tus propios proyectos. Si eso ocurre, ¡siéntete libre de compartir el enlace de tu proyecto en los comentarios!
Más proyectos de JavaScript para "condimentar" tus sitios web
- DesempeñoMejora del rendimiento: cómo cargar imágenes utilizando in-view.jsLouie Rootfield
- FlickityCreando un slider con Flickity de MetafizzyThoriq Firdaus
- jQueryConsejo rápido: Animaciones al desplazarse con fullPage.js y Animate.cssGeorge Martsoukos
- JavaScriptCómo crear un slider a pantalla dividida con JavaScriptAdi Purdila