Creación de una galería de imágenes modal con componentes Bootstrap | Programar Plus

¿Alguna vez ha hecho clic en una imagen en una página web que abre una versión más grande de la imagen con navegación para ver otras fotos?

Algunas personas lo llaman ventana emergente. Otros lo llaman caja de luz. Bootstrap lo llama modal. Menciono Bootstrap porque quiero usarlo para hacer el mismo tipo de cosas. Entonces, llamémoslo modal de aquí en adelante.

¿Por qué Bootstrap? usted podría preguntar. Bueno, algunas razones:

  • Ya estoy usando Bootstrap en el sitio donde quiero este efecto, por lo que no hay gastos generales adicionales en términos de recursos de carga.
  • Quiero algo donde tenga un control completo y sencillo sobre la estética. Bootstrap es una pizarra limpia en comparación con la mayoría de los complementos modales con los que me he encontrado.
  • La funcionalidad que necesito es bastante simple. No hay mucho que ganar codificando todo desde cero. Considero que el tiempo que ahorro usando el marco Bootstrap es más beneficioso que cualquier inconveniente potencial.

Aquí es donde terminaremos:

Repasemos eso, poco a poco.

Paso 1: crea la cuadrícula de la galería de imágenes

Comencemos con el marcado para un diseño de cuadrícula de imágenes. Podemos usar el sistema de cuadrícula de Bootstrap para eso.

<div class="row" id="gallery">
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="https://css-tricks.com/image-1">
  </div>
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="https://css-tricks.com/image-2">
  </div>
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="https://css-tricks.com/image-3">
  </div>
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="https://css-tricks.com/image-4">
  </div>
</div>

Ahora necesitamos atributos de datos para que esas imágenes sean interactivas. Bootstrap analiza los atributos de los datos para determinar qué elementos deben ser interactivos y qué deben hacer. En este caso, crearemos interacciones que abren el componente modal y permiten desplazarse por las imágenes utilizando el componente carrusel.

Acerca de esos atributos de datos:

  1. Agregaremos data-toggle="modal" y data-target="#exampleModal" al elemento padre (#gallery). Esto hace que al hacer clic en cualquier elemento de la galería se abra el modal. También debemos agregar el valor de destino de datos (#exampleModal) como el ID del modal en sí, pero lo haremos una vez que lleguemos al marcado modal.
  2. Agreguemos data-target="https://css-tricks.com/creating-a-modal-image-gallery-with-bootstrap-components/#carouselExample" y un data-slide-to atributo a cada imagen. En su lugar, podríamos agregarlos a los envoltorios de imágenes, pero iremos con las imágenes en esta publicación. Más adelante, querremos usar el valor de destino de datos (#carouselExample) como ID para el carrusel, así que tenlo en cuenta para cuando lleguemos allí. Los valores para data-slide-to se basan en el orden de las imágenes.

Esto es lo que obtenemos cuando juntamos eso:

<div class="row" id="gallery" data-toggle="modal" data-target="#exampleModal">
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="https://css-tricks.com/image-1.jpg" data-target="https://css-tricks.com/creating-a-modal-image-gallery-with-bootstrap-components/#carouselExample" data-slide-to="0">
  </div>
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="https://css-tricks.com/image-2.jpg" data-target="https://css-tricks.com/creating-a-modal-image-gallery-with-bootstrap-components/#carouselExample" data-slide-to="1">
  </div>
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="https://css-tricks.com/image-3.jpg" data-target="https://css-tricks.com/creating-a-modal-image-gallery-with-bootstrap-components/#carouselExample" data-slide-to="2">
  </div>
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="https://css-tricks.com/image-4.jpg" data-target="https://css-tricks.com/creating-a-modal-image-gallery-with-bootstrap-components/#carouselExample" data-slide-to="3">
  </div>
</div>

¿Le interesa saber más sobre los atributos de los datos? Consulte la guía Programar Pluspara ellos.

Paso 2: haz que el modal funcione

Este es un carrusel dentro de un modal, los cuales son componentes estándar de Bootstrap. Aquí solo estamos anidando uno dentro del otro. Prácticamente un trabajo sencillo de copiar y pegar de la documentación de Bootstrap.

Sin embargo, aquí hay algunas partes importantes a tener en cuenta:

  1. El ID modal debe coincidir con el data-target del elemento de la galería.
  2. El ID del carrusel debe coincidir con el data-target de las imágenes de la galería.
  3. Las diapositivas del carrusel deben coincidir con las imágenes de la galería y deben estar en el mismo orden.

Aquí está el marcado para el modal con nuestros atributos en su lugar:

<!-- Modal markup: https://getbootstrap.com/docs/4.4/components/modal/ -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">×</span>
        </button>
      </div>
      <div class="modal-body">
        
      <!-- Carousel markup goes here -->


      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>

Podemos colocar el marcado del carrusel allí mismo, ¡al estilo Voltron!

<!-- Modal markup: https://getbootstrap.com/docs/4.4/components/modal/ -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">×</span>
        </button>
      </div>
      <div class="modal-body">
        
      <!-- Carousel markup: https://getbootstrap.com/docs/4.4/components/carousel/ -->
      <div id="carouselExample" class="carousel slide" data-ride="carousel">
          <div class="carousel-inner">
            <div class="carousel-item active">
              <img class="d-block w-100" src="https://css-tricks.com/image-1.jpg">
            </div>
            <div class="carousel-item">
              <img class="d-block w-100" src="https://css-tricks.com/image-2.jpg">
            </div>
            <div class="carousel-item">
              <img class="d-block w-100" src="https://css-tricks.com/image-3.jpg">
            </div>
            <div class="carousel-item">
              <img class="d-block w-100" src="https://css-tricks.com/image-4.jpg">
            </div>
          </div>
          <a class="carousel-control-prev" href="https://css-tricks.com/creating-a-modal-image-gallery-with-bootstrap-components/#carouselExample" role="button" data-slide="prev">
            <span class="carousel-control-prev-icon" aria-hidden="true"></span>
            <span class="sr-only">Previous</span>
          </a>
          <a class="carousel-control-next" href="https://css-tricks.com/creating-a-modal-image-gallery-with-bootstrap-components/#carouselExample" role="button" data-slide="next">
            <span class="carousel-control-next-icon" aria-hidden="true"></span>
            <span class="sr-only">Next</span>
          </a>
        </div>
      </div>

      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>

Parece mucho código, ¿verdad? Nuevamente, es básicamente directamente de los documentos de Bootstrap, solo con nuestros atributos e imágenes.

Paso 3: ocuparse de los tamaños de imagen

Esto no es necesario, pero si las imágenes en el carrusel tienen diferentes dimensiones, podemos recortarlas con CSS para mantener la coherencia. Tenga en cuenta que estamos usando Sass aquí.

// Use Bootstrap breakpoints for consistency.
$bootstrap-sm: 576px;
$bootstrap-md: 768px;
$bootstrap-lg: 992px;
$bootstrap-xl: 1200px;


// Crop thumbnail images.
#gallery {
  img {
    height: 75vw;
    object-fit: cover;
    
    @media (min-width: $bootstrap-sm) {
      height: 35vw;
    }
    
    @media (min-width: $bootstrap-lg) {
      height: 18vw;
    }
  }
}


// Crop images in the coursel
.carousel-item {
  img {
    height: 60vw;
    object-fit: cover;
    
    @media (min-width: $bootstrap-sm) {
      height: 350px;
    }
  }
}

Paso 4: Optimiza las imágenes

Es posible que haya notado que el marcado usa los mismos archivos de imagen en la galería que nosotros en el modal. Ese no tiene por qué ser el caso. De hecho, es una mejor idea utilizar versiones más pequeñas y de mayor rendimiento de las imágenes para la galería. Vamos a ampliar las imágenes a su versión de tamaño completo de todos modos en el modal, por lo que no es necesario tener la mejor calidad al principio.

Lo bueno del enfoque de Bootstrap aquí es que podemos usar diferentes imágenes en la galería que en el modal. No son mutuamente excluyentes cuando tienen que apuntar al mismo archivo.

Entonces, para eso, sugiero actualizar el marcado de la galería con imágenes de menor calidad:

<div class="row" id="gallery" data-toggle="modal" data-target="#exampleModal">
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="https://css-tricks.com/image-1-small.jpg" data-target="https://css-tricks.com/creating-a-modal-image-gallery-with-bootstrap-components/#carouselExample" data-slide-to="0">
  
  <!-- and so on... -->
</div>

¡Eso es!

El sitio donde estoy usando esto ya tiene el tema Bootstrap. Eso significa que todo ya está diseñado según las especificaciones. Dicho esto, incluso si no tienes Bootstrap temático, ¡aún puedes agregar estilos personalizados fácilmente! Con este enfoque (Bootstrap frente a complementos), la personalización es sencilla porque tiene un control completo sobre el marcado y el estilo de Bootstrap es relativamente escaso.

Aquí está la demostración final: