22/10/2013
En el dinámico mundo del diseño web, captar la atención del usuario en los primeros segundos es crucial. Una de las herramientas más efectivas y visualmente atractivas para lograrlo es el "Story Slider", un componente interactivo inspirado en las populares historias de plataformas como Instagram o Facebook. Este tipo de slider permite presentar contenido, ya sean imágenes o videos, de una manera secuencial, inmersiva y muy familiar para el usuario moderno. Implementar esta funcionalidad desde cero puede ser un desafío, pero gracias a librerías como Swiper.js, el proceso se vuelve increíblemente accesible.

En este completo artículo, te guiaremos paso a paso para que puedas construir tu propio slider de historias utilizando las tecnologías web fundamentales: HTML para la estructura, CSS para el estilo y JavaScript para la interactividad, todo ello potenciado por la robusta librería Swiper.js. No solo te proporcionaremos el código listo para usar, sino que también desglosaremos cada parte para que comprendas su funcionamiento y puedas adaptarlo a las necesidades de tu proyecto. ¡Prepárate para llevar la experiencia de usuario de tu sitio web al siguiente nivel!
¿Qué es un Slider y por qué usar Swiper.js?
Un "slider", también conocido como carrusel o deslizador, es un componente de la interfaz de usuario que muestra una serie de elementos (imágenes, videos, texto) uno a la vez o en grupos, permitiendo al usuario navegar entre ellos. Son extremadamente útiles para mostrar una gran cantidad de contenido en un espacio reducido, como en galerías de productos, portafolios o, como en nuestro caso, secuencias de historias.
Existen muchas formas de crear un slider, pero pocas son tan potentes y flexibles como Swiper.js. Se trata de una librería de JavaScript de código abierto, moderna y gratuita, especializada en la creación de sliders táctiles y responsivos. Sus principales ventajas son:
- Rendimiento optimizado: Está diseñado para ser rápido y fluido, incluso en dispositivos móviles con menos recursos.
- Mobile-First: Su enfoque principal es la experiencia táctil, lo que lo hace perfecto para el diseño web responsivo.
- Altamente personalizable: Ofrece una API muy completa con cientos de parámetros y eventos que permiten un control total sobre el comportamiento y la apariencia del slider.
- Múltiples funcionalidades: Soporta efectos de transición avanzados (como Coverflow, Cube), paginación, navegación, lazy loading, autoplay y mucho más.
- Gran comunidad y documentación: Cuenta con una documentación exhaustiva y una comunidad activa que facilita la resolución de dudas.
Para nuestro proyecto de Story Slider, Swiper.js es la elección ideal porque nos proporciona el motor subyacente para el carrusel, el control del autoplay y los eventos necesarios para construir nuestra lógica de barras de progreso personalizadas.
Paso 1: Preparando el Entorno y las Dependencias
Antes de escribir una sola línea de nuestro slider, debemos asegurarnos de que nuestro proyecto tenga acceso a las librerías necesarias. Para este tutorial, utilizaremos una red de distribución de contenidos (CDN), que es la forma más rápida de empezar. Simplemente necesitas un archivo HTML básico.
Primero, en la etiqueta <head> de tu documento HTML, añade el enlace a la hoja de estilos de Swiper.js. Esto asegurará que todos los estilos base del slider se carguen correctamente.

<!-- Swiper CSS --> <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.css'>Luego, justo antes de cerrar la etiqueta </body>, añade los scripts de Swiper.js y otras dos librerías que usaremos para facilitar ciertas tareas: jQuery para una selección de elementos más sencilla y GSAP (GreenSock Animation Platform) para animar nuestras barras de progreso de forma fluida y eficiente.
<!-- Swiper JS --> <script src='https://cdnjs.cloudflare.com/ajax/libs/Swiper/10.1.0/swiper-bundle.min.js'></script> <!-- jQuery --> <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js'></script> <!-- GSAP --> <script src='https://unpkg.co/gsap@3/dist/gsap.min.js'></script>Con estas líneas en su lugar, nuestro entorno está listo para empezar a construir.
Paso 2: La Estructura HTML del Slider
El HTML define el esqueleto de nuestro componente. La estructura para un slider de Swiper es bastante específica y se basa en un conjunto de clases predefinidas que la librería utiliza para identificar cada parte.
Copia y pega el siguiente código en el <body> de tu archivo HTML:
<div class="story"> <div class="story__slider swiper"> <div class="story__wrapper swiper-wrapper"> <!-- Slide 1: Imagen --> <div class="story__slide swiper-slide"> <img src="https://picsum.photos/450/800" /> </div> <!-- Slide 2: Video --> <div class="story__slide swiper-slide"> <video autoplay muted> <source src="https://exit109.com/~dnn/clips/RW20seconds_1.mp4#t=.1" type="video/mp4"> </video> </div> <!-- Slide 3: Imagen --> <div class="story__slide swiper-slide"> <img src="https://picsum.photos/450/810" /> </div> </div> <!-- Botones de Navegación --> <div class="story__next swiper-button-next"></div> <div class="story__prev swiper-button-prev"></div> <!-- Paginación (Barras de Progreso) --> <div class="story__pagination swiper-pagination"></div> </div> </div>Análisis de la Estructura:
.story__slider.swiper: Es el contenedor principal que Swiper inicializará..swiper-wrapper: Este es el contenedor directo de todos los slides. Swiper aplicará transformaciones a este elemento para crear el efecto de deslizamiento..swiper-slide: Cada uno de estos divs representa una historia individual. Dentro puedes colocar cualquier contenido: imágenes, videos, texto, etc..swiper-button-nexty.swiper-button-prev: Son los elementos que funcionarán como botones para navegar hacia adelante y hacia atrás..swiper-pagination: Este div será el contenedor de nuestras barras de progreso.
Paso 3: Dando Estilo con CSS
Ahora que tenemos la estructura, vamos a darle una apariencia similar a la de las historias de redes sociales. El siguiente código CSS define el tamaño del slider, asegura que las imágenes y videos llenen el espacio disponible y personaliza la paginación y la navegación.

.story__slider { width: 450px; height: 800px; border-radius: 6px; overflow: hidden; } .story__slide { position: relative; } .story__slide video, .story__slide img { height: 100%; width: 100%; object-fit: cover; object-position: center; } .story__pagination { bottom: unset !important; top: 8px !important; display: flex; padding: 0 4px; } .story__pagination .swiper-pagination-bullet { flex-grow: 1; border-radius: 100vh; height: 3px; margin: 0 2px !important; background-color: rgba(247, 247, 245, 0.4); opacity: 1; } .story__pagination .swiper-pagination-bullet .swiper-pagination-progress { height: 100%; width: 0%; border-radius: 100vh; background-color: #f7f7f5; } .story__prev, .story__next { height: 100%; width: 50%; top: 0; margin-top: 0; } .story__prev::after, .story__next::after { content: none; } .story__prev { left: 0; } .story__next { right: 0; }Claves del CSS:
.story__slider: Establece un tamaño fijo y bordes redondeados. Eloverflow: hiddenes vital para que el contenido de los slides no se salga del contenedor.object-fit: cover: Esta propiedad es la magia que hace que las imágenes y videos cubran todo el slide sin deformarse, recortando el exceso si es necesario..story__pagination: Movemos la paginación a la parte superior (top: 8px) y usamos Flexbox para que los "bullets" se distribuyan equitativamente..swiper-pagination-bullet: Le damos estilo a cada segmento de la barra de progreso, con un fondo semitransparente..swiper-pagination-progress: Este será el elemento que animaremos para mostrar el progreso. Inicialmente tiene un ancho de 0..story__prev, .story__next: Un truco interesante aquí es hacer que los botones de navegación ocupen el 50% izquierdo y derecho de todo el slider. Esto permite al usuario hacer clic en cualquier parte de la mitad de la pantalla para avanzar o retroceder, una experiencia de usuario muy intuitiva. También eliminamos los iconos de flecha predeterminados concontent: none.
Paso 4: La Lógica con JavaScript
Aquí es donde todo cobra vida. El código JavaScript se encargará de inicializar Swiper con la configuración adecuada y de manejar la lógica de las barras de progreso animadas.
// Establecer la duración para los slides con video const videos = document.querySelectorAll('.story__slide video'); videos.forEach(video => { $(video).parent('.story__slide').attr('data-swiper-autoplay', video.duration * 1000); }); const slider = new Swiper(".story__slider", { speed: 1, watchSlidesProgress: true, loop: true, autoplay: { delay: 15000, // Duración por defecto para imágenes disableOnInteraction: false }, slidesPerView: 1, navigation: { nextEl: ".story__next", prevEl: ".story__prev", }, pagination: { el: '.story__pagination', renderBullet: function (index, className) { // Renderizar una estructura personalizada para cada bullet return '<div class="' + className + '"> <div class="swiper-pagination-progress"></div> </div>'; } }, // Eventos personalizados on: { autoplayTimeLeft(swiper, time, progress) { let currentSlide = document.querySelectorAll('.story__slider .swiper-slide')[swiper.activeIndex]; let currentBullet = document.querySelectorAll('.story__slider .swiper-pagination-progress')[swiper.realIndex]; let fullTime = currentSlide.dataset.swiperAutoplay ? parseInt(currentSlide.dataset.swiperAutoplay): swiper.params.autoplay.delay; let percentage = Math.min(Math.max(parseFloat(((fullTime - time) * 100 / fullTime).toFixed(1)), 0), 100) + '%'; gsap.set(currentBullet, {width: percentage}); }, transitionEnd(swiper) { let allBullets = $('.story__slider .swiper-pagination-progress'); let bulletsBefore = allBullets.slice(0, swiper.realIndex); let bulletsAfter = allBullets.slice(swiper.realIndex, allBullets.length); if(bulletsBefore.length) {gsap.set(bulletsBefore, {width: '100%'})} if(bulletsAfter.length) {gsap.set(bulletsAfter, {width: '0%'})} // Reiniciar el video si el slide activo contiene uno let activeSlide = document.querySelectorAll('.story__slider .swiper-slide')[swiper.realIndex]; if (activeSlide.querySelector('video')) { activeSlide.querySelector('video').currentTime = 0; } }, } });Desglose del Código JavaScript:
- Duración del video: El primer bloque de código es muy ingenioso. Recorre todos los elementos
<video>, obtiene su duración en segundos, la convierte a milisegundos y la establece como un atributodata-swiper-autoplayen el slide padre. Swiper reconoce este atributo y lo usará para determinar cuánto tiempo debe mostrarse ese slide específico, ignorando el `delay` por defecto. - Inicialización de Swiper: Creamos una nueva instancia de Swiper, pasándole el selector de nuestro contenedor y un objeto de configuración.
- Configuración:
loop: true: Hace que el slider sea infinito.autoplay: Establece un tiempo por defecto de 15 segundos para las imágenes.navigation: Vincula los botones HTML a la funcionalidad de Swiper.pagination: Aquí ocurre la magia. ConrenderBullet, en lugar de renderizar un simple punto, le decimos a Swiper que cree un div que contiene nuestra barra de progreso (.swiper-pagination-progress).
- Eventos (`on`):
autoplayTimeLeft: Este evento se dispara continuamente mientras el autoplay está activo. Lo usamos para calcular el porcentaje de tiempo transcurrido y, con la ayuda de GSAP, actualizamos el ancho (`width`) de la barra de progreso del slide actual en tiempo real. Esto crea la animación de llenado.transitionEnd: Este evento se dispara cuando una transición de slide termina. Lo usamos para poner el estado de las barras de progreso en orden: todas las anteriores al slide actual se llenan al 100%, y todas las posteriores se vacían al 0%. Además, si el nuevo slide activo contiene un video, lo reiniciamos al segundo 0 para que siempre comience desde el principio.
Preguntas Frecuentes (FAQ)
- ¿Cómo puedo añadir más historias?
- Es muy sencillo. Simplemente añade más elementos
<div class="story__slide swiper-slide">...</div>dentro del contenedor.swiper-wrapperen tu HTML. El script de JavaScript se adaptará automáticamente. - ¿Cómo cambio la duración de las diapositivas de imagen?
- En el código JavaScript, dentro de la inicialización de Swiper, busca la propiedad
autoplay. Cambia el valor dedelay: 15000al número de milisegundos que desees (por ejemplo, 5000 para 5 segundos). - ¿Es obligatorio usar jQuery y GSAP?
- En este código específico, sí. jQuery se usa para la selección de elementos de forma concisa y GSAP para las animaciones. Sería posible reescribir estas partes con JavaScript puro (Vanilla JS), pero requeriría un código más verboso para lograr el mismo resultado fluido.
- El slider no es responsivo, ¿cómo lo soluciono?
- El CSS proporcionado utiliza un ancho y alto fijos (
450pxy800px). Para hacerlo responsivo, puedes usar unidades relativas como porcentajes o `vw`/`vh` y emplear Media Queries en tu CSS para ajustar estas dimensiones en diferentes tamaños de pantalla. Por ejemplo:.story__slider { width: 100%; max-width: 450px; height: 90vh; }.
Conclusión
¡Felicidades! Has construido con éxito un slider de historias funcional, moderno y visualmente atractivo utilizando HTML, CSS y JavaScript con la ayuda de Swiper.js. Has aprendido no solo a implementar un carrusel básico, sino también a personalizar su comportamiento y apariencia de forma avanzada, creando una paginación personalizada que imita una de las características de interfaz de usuario más reconocibles de la actualidad.
Este proyecto es un excelente punto de partida. Te animamos a experimentar: cambia los colores, añade animaciones de texto sobre las imágenes, integra contenido desde una API o ajusta los parámetros de Swiper para descubrir todo el potencial que esta increíble librería tiene para ofrecer. Ahora tienes una herramienta más en tu arsenal para crear sitios web más dinámicos y atractivos.
Si quieres conocer otros artículos parecidos a Crea un Slider de Historias con Swiper.js puedes visitar la categoría Juegos.
