Carousel en CSS con Mandatory y diapositivas en bloques de HTML

3 minutos

HTML5 y CSS3

En algunas ocasiones necesitamos que cada diapositiva tenga HTML, en lugar de ser únicamente una imagen. Queremos añadir textos, títulos, etc. Es relativamente sencillo de construir gracias a CSS3 con un extra de JavaScript para automatizar el cambio entre ellas y su retardo. Entre sus características:

Demo

Código

El HTML es mínimo. Puedes añadir más diapositivas, o cambiar el HTML dentro del <article>. Solo debes mantener las clases en su lugar para que coincida con los selectores de JavaScript.

<section class="carousel">
  <div class="carousel__container">
    <article class="carousel__slider carousel__slider--1">
      <h1>Mi título 1</h1>
      <p>Mi HTML 1</p>
    </article>
    <article class="carousel__slider carousel__slider--2">
      <h1>Mi título 2</h1>
      <p>Mi HTML 2</p>
    </article>
    <article class="carousel__slider carousel__slider--3">
      <h1>Mi título 3</h1>
      <p>Mi HTML 3</p>
    </article>
  </div>
</section>

El CSS solo esta de ejemplo para maquetarlo mínimamente. Estiliza a tu gusto.

:root {
  --carousel-height: 20rem;
  --carousel-width: 40rem;
}
/* Oculta el scroll horizontal */
.carousel {
  height: var(--carousel-height);
  overflow: hidden;
  width: var(--carousel-width);
}

.carousel__container {
  scroll-snap-type: x mandatory;
  display: flex;
  overflow-x: auto;
}

.carousel__slider {
  height: var(--carousel-height);
  min-width: var(--carousel-width);
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
  scroll-snap-align: start;
}

.carousel__slider--1 {
  background-image: url("https://source.unsplash.com/featured/1000x400/?fish");
}

.carousel__slider--2 {
  background-image: url("https://source.unsplash.com/featured/1000x400/?cat");
}

.carousel__slider--3 {
  background-image: url("https://source.unsplash.com/featured/1000x400/?dog");
}

/* Estilos para la demo, pueden ser borrados */
.carousel__slider h1,
.carousel__slider p {
  color: white;
  text-shadow: 1px 1px 5px black;
}
/* Fin Estilos para la demo, pueden ser borrados */

Dentro del JavaScript te interesa revisar la variables.


// Variables
const SEGUNDOS_ENTRE_DIAPOSITIVAS = 2; // <---- IMPORTANTE
const CAROUSEL = document.querySelector(".carousel");
const SLIDERS = CAROUSEL.querySelectorAll(".carousel__slider");

// Funciones

async function autoPlay(posicionPartida = SLIDERS.length) {
  // Obtiene el siguiente indice
  const SIGUIENTE_POSICION =
    SLIDERS.length - 1 > posicionPartida ? posicionPartida + 1 : 0;
  // Mueve el scroll al siguiente slider
  SLIDERS[SIGUIENTE_POSICION].scrollIntoView({ block: "center" });
  // Retardo antes de volver a ejecutarse
  await new Promise((res) => {
    setTimeout(res, SEGUNDOS_ENTRE_DIAPOSITIVAS * 1000);
  });
  // Creamos un objeto IntersectionObserver
  observerCarousel = new IntersectionObserver((entries) => {
        // Comprobamos todas las intesecciones.
        entries.forEach((entry) => {
            // Si es observable, entra
            if (entry.isIntersecting) {
              // Activamos
              autoPlay(SIGUIENTE_POSICION)
            }
        });
    });

  // Añado a mi Observable que quiero observar. En este caso el carousel
  observerCarousel.observe(CAROUSEL);
}

// Ejecuta
autoPlay();


Ejemplo completo


<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Ejemplo</title>
    <style type="text/css" media="screen">
      :root {
        --carousel-height: 20rem;
        --carousel-width: 40rem;
      }
      /* Oculta el scroll horizontal */
      .carousel {
        height: var(--carousel-height);
        overflow: hidden;
        width: var(--carousel-width);
      }

      .carousel__container {
        scroll-snap-type: x mandatory;
        display: flex;
        overflow-x: auto;
      }

      .carousel__slider {
        height: var(--carousel-height);
        min-width: var(--carousel-width);
        background-repeat: no-repeat;
        background-size: cover;
        background-position: center;
        scroll-snap-align: start;
      }

      .carousel__slider--1 {
        background-image: url("https://source.unsplash.com/featured/1000x400/?fish");
      }

      .carousel__slider--2 {
        background-image: url("https://source.unsplash.com/featured/1000x400/?cat");
      }

      .carousel__slider--3 {
        background-image: url("https://source.unsplash.com/featured/1000x400/?dog");
      }

      /* Estilos para la demo, pueden ser borrados */
      .carousel__slider h1,
      .carousel__slider p {
        color: white;
        text-shadow: 1px 1px 5px black;
      }
      /* Fin Estilos para la demo, pueden ser borrados */
    </style>
</head>
<body>
  <section class="carousel">
    <div class="carousel__container">
      <article class="carousel__slider carousel__slider--1">
        <h1>Mi título 1</h1>
        <p>Mi HTML 1</p>
      </article>
      <article class="carousel__slider carousel__slider--2">
        <h1>Mi título 2</h1>
        <p>Mi HTML 2</p>
      </article>
      <article class="carousel__slider carousel__slider--3">
        <h1>Mi título 3</h1>
        <p>Mi HTML 3</p>
      </article>
    </div>
  </section>
  <script>
    // Variables
    const SEGUNDOS_ENTRE_SLIDERS = 2; // <---- IMPORTANT
    const CAROUSEL = document.querySelector(".carousel");
    const SLIDERS = CAROUSEL.querySelectorAll(".carousel__slider");
    let observerCarousel;

    // Funciones

    async function autoPlay(posicionPartida = SLIDERS.length) {
      // Elimina los IntersectionObserver para evitar que se reproduzca si no mira el usuario
      if(observerCarousel !== undefined) observerCarousel.unobserve(CAROUSEL)

      // Obtiene el siguiente indice
      const SIGUIENTE_POSICION =
        SLIDERS.length - 1 > posicionPartida ? posicionPartida + 1 : 0;
      // Mueve el scroll al siguiente slider
      SLIDERS[SIGUIENTE_POSICION].scrollIntoView({ block: "center" });
      // Retardo antes de volver a ejecutarse
      await new Promise((res) => {
        setTimeout(res, SEGUNDOS_ENTRE_SLIDERS * 1000);
      });
      // Ejecutamos el autoPlay únicamente cuando sea visible
      // Creamos un objeto IntersectionObserver
      observerCarousel = new IntersectionObserver((entries) => {
            // Comprobamos todas las intesecciones.
            entries.forEach((entry) => {
                // Si es observable, entra
                if (entry.isIntersecting) {
                  // Activamos
                  autoPlay(SIGUIENTE_POSICION)
                }
            });
        });

      // Añado a mi Observable que quiero observar. En este caso el carousel
      observerCarousel.observe(CAROUSEL);
    }

    // Ejecuta
    autoPlay();
  </script>
</body>
</html>

Si quieres un ejemplo sin bloques de HTML y mucho más simple: Sencillo carousel con controles y autoreproducción.

Donación con recompensa

Comprame un café
  • 1 café: Respondo a tu duda en los comentarios.
  • 2 cafés: Respondo en menos de 24h a tu comentario.
  • 3 cafés: Todo lo anterior y además te doy las gracias en mis redes.

Comentarios

{{ comments.length }} comentarios

Nuevo comentario

Nueva replica  {{ formatEllipsisAuthor(replyComment.author) }}

Acepto la política de Protección de Datos.

Escribe el primer comentario

Tal vez también te interese...