Cuadricula flexbox

facebook-svg gplus-svg twitter-svg

Lo que queremos conseguir es una serie de tarjetas de igual tamaño, colocadas en cuadricula. ( vea este ejemplo en codepen.io ) Quien lo haya intentado utilizando cajas flotantes sabe que no es nada fácil, sobretodo si queremos crear estas cajas de manera dinámica.

Estructura de una tarjeta

Primero dibujamos la "tarjeta" que tiene mas o menos esta estructura ( inspirada en las tarjetas de pinterest.com pero mucho más sencilla ): Dentro del envoltorio <div class ="pinWrapper "> hay dos elementos: un <div class ="pinImage "> para la imagen y la descripción de esta,  y un párafo <p class="pin CreditTitle"> para acreditar la proveniencia de la imagen.  

<div class="pinWrapper">
<!-- un div para la imagen y la descripción de esta-->
<div class="pinImage">
    <img src="http://www.placecage.com/236/293" alt="Nicolas Cage">
    <h3 class="pin GridTitle">Pablo Picasso</h3><!-- opcional -->
    <p class="pin Description">Don Quixote. Uno de mis dibujos favoritos, quizás por mi predilección por el hidalgo indomable.</p>
  </div>
<!-- un párafo para acreditar la proveniencia de la imagen -->  
<p class="pin CreditTitle"><strong>Pinned from</strong>:<br>
  Uploaded by user</p>
</div>

Esta estructura tan sencilla nos permite crear fácilmente el HTML de manera dinámica, utilizando php o javascript, o lo que queramos.

Los estilos para el envoltorio

.pinWrapper {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    flex: 0 1 calc(50% - 1em);
}

Después de dar al envoltorio una serie de estilos básicos, lo transformamos en una caja flexible utilizando:

display: flex;

Dentro de esta caja queremos colocar los elementos en dirección vertical por lo cual necesitamos uitilizar la propiedad flex-direction:

flex-direction: column;

También queremos que el párrafo para acreditar la proveniencia de la imagen <p class="pin CreditTitle"> esté siempre a la parte de abajo. La solución es utilizar la propiedad justify-content

justify-content: space-between;

Finalmente escribimos esta línea de código: flex: 0 1 calc(50% - 1em); que también la podemos escribir así:

/*flex-grow:0;*/
  flex-shrink:1;
  flex-basis: calc(50% - 1em);

Recuerde que la propiedad flex nos permite abreviar tres propiedades: flex-grow, flex-shrink y flex-basis en una sola.

Esto traducido al castellano quiere decir que:

  • 1. Las tarjetas no pueden crecer flex-grow:0;.
  • 2. Las tarjetas pueden contraerse lo que fuera necesario para acomodarse dentro del contenedor: flex-shrink:1;
  • 3. Asimismo damos a la tarjeta una anchura de 50% del contenedor, o sea de la galería. Para esto podemos utilizar la propiedad width:50%, pero dentro de una caja flex es aconsejable utilizar flex-basis:50%. De estos 50% restamos 1em que equivale a un margen margin:.5em;
flex-basis: calc(50% - 1em);
Veamos el código:

.pinWrapper {
  padding: 0;
  border: 1px solid #d9d9d9;
  border-radius: 6px;
  overflow: hidden;
  background-color: white;
  margin: .5em;
}

.pinWrapper p {
  font-size: .8em;
}

.pin {
  padding: .8em;
}

.CreditTitle {
  border-top: 1px solid #e0e0e0;
}

.pinImage img {
  width: 100%;
}


/* FLEXBOX */

.pinWrapper {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  flex: 0 1 calc(50% - 1em);
}


Nicolas Cage

Pablo Picasso

Don Quixote. Uno de mis dibujos favoritos, quizás por mi predilección por el hidalgo indomable.

Pinned from:
Uploaded by user

Nicolas Cage

Pablo Picasso

Don Quixote. Uno de mis dibujos favoritos, quizás por mi predilección por el hidalgo indomable.

Pinned from:
Uploaded by user

Las imágenes utilizadas provienen de www.placecage.com una plataforma que nos permite emplear fácilmente imágenes marcadoras de posición.

Los estilos para la galería de imágenes

También la galería tiene una estructura HTML muy sencilla: dentro del  <div id="pinTerest">  ( la galería ) aparecen anidadas las tarjetas <div class="pinWrapper">; y nada más.

<div class="pinTerest">
    <div class="pinWrapper"></div>
    <div class="pinWrapper"></div>
    <div class="pinWrapper"></div>
    <div class="pinWrapper"></div>
    . . . . . . .
</div>

Después de dar a la galería una serie de estilos básicos, la transformamos en una caja flexible, utilizando display: flex;. Dentro de esta caja queremos colocar los elementos en dirección horizontal por lo cual podemos escribir flex-direction: row; pero no es necesario ya que row es el valor que toma por defecto la propiedad flex-direction.
La propiedad flex-wrap  especifica si puede haber un cambio de línea ( wrap ) o no ( nowrap – el valor por defecto ). Si no hay cambio de línea todos los elementos aparecen apretados y aplastados para que quepan en una sola hilera. Para que esto no pase utilizamos  flex-wrap: wrap.

#pinTerest {  
    display: flex;
    flex-wrap: wrap;
  }

@media queries

Cuando trabajamos con @media queries es mejor empezar por los estilos para las pantallas pequeñas. Es por esto que las tarjetas tienen una anchura base de 50%: flex-basis: calc(50% - 1em);

.pinWrapper {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    flex: 0 1 calc(50% - 1em);
  }

En pantallas más grandes queremos cambiar la anchura base ( flex-basis ) de las tarjetas para que quepan 3, 4 o 5 tarjetas en una fila:

@media screen and ( min-width:30em) {   .pinWrapper {     flex: 0 1 calc(33% - 1em); /* 3 tarjetas en fila*/   } }

@media screen and ( min-width:48em) {   .pinWrapper {     flex: 0 1 calc(25% - 1em); /* 4 tarjetas en fila*/   } }

@media screen and ( min-width:62em) {   .pinWrapper {     flex: 0 1 calc(20% - 1em); /* 5 tarjetas en fila*/   } }

See the Pen Responsive Image Gallery With Flexbox by Gabi (@enxaneta) on CodePen.

Las imágenes utilizadas provienen de www.placecage.com una plataforma que nos permite uzar fácilmente imágenes marcadoras de posición.