En este tutorial vamos a aprender cómo hacer, de una forma muy sencilla y solo con HTML y CSS, una galería de imágenes responsive (o una galería de cualquier otro elemento) al estilo Pinterest. Esto es, tenemos imágenes de distinto tamaño que no se alinean horizontalmente, sino verticalmente en columnas.
Nota: Aunque a día de hoy puedes seguir usando esta técnica, te recomiendo hacerlo con CSS Grid-Layout. Te resultará más fácil y tendrás mucho más control sobre la maquetación. Y si aún no "controlas" CSS Grid, ya estás tardando en hacerte este curso. ;-)
Doy por hecho que sabes qué es Pinterest ¿no? Pinterest es un sitio/plataforma/red social donde se pueden compartir imágenes de forma sencilla y clasificarlas en forma de tableros, como si fueran los típicos tableros de corcho donde se sujetan cosas importantes. A la acción de subir una imagen a Pinterest se la conoce como pinear (de pin, alfiler en inglés).
Pinterest se lanzó en 2010, y sorprendió no solo por la rápida popularidad que adquirió, sino también por la peculiar forma de disponer las imágenes pineadas.
Realmente no inventaron nada nuevo, pero sí que lo popularizaron. Esta técnica era una tendencia que ya se venía usando de forma experimental entre diseñadores y desarrolladores front usando una biblioteca de jQuery llamada Masonry, aunque con resultados discretos.
El gran mérito de Pinterest es ser el primer sitio mainstream en implementar con éxito esta peculiar interfaz, y, por tanto, popularizarla (valga la redundancia). El diseño de la interfaz se ha ido mejorando con el tiempo, pero su esencia permanece:
Offtopic: Efectivamente, te has dado cuenta, el logo de Pinterest no siempre ha sido rojo. Mira por dónde, hoy aprendes dos cosas por el precio de una. :-D
Por aquel entonces esta presentación solo se podía conseguir con JavaScript, y la manera más sencilla era tirando de jQuery y la anteriormente mencionada biblioteca Masonry, llamado así porque los elementos se apilan de forma similar a los ladrillos de un muro, pero en vertical.
Su funcionamiento a grandes rasgos era así: los elementos de la galería se flotaban y Masonry se encargaba de buscarles el hueco que mejor le encajaba por su tamaño, independientemente del flujo del documento.
Construyendo nuestra galería estilo Pinterest sólo con HTML y CSS
Para este ejemplo voy a usar imágenes de libros y cursos de programación de campusMVP para nuestra lista de elementos de la galería:
Los productos están envueltos por un contenedor <section>
centrado y con un ancho máximo de 960px, y que tiene dentro el <h1>
que da título a la página. Cada ítem de producto consta de una imagen y el nombre del curso, siguiendo esta estructura:
<section id="galeria">
<header>
<h1>Cursos y libros de campusMVP</h1>
</header>
<article>
<a href="https://www.campusmvp.es/catalogo/Product-Desarrollo-de-aplicaciones-web-con-Angular-7_232.aspx" target="_blank">
<figure>
<img src="imagenes/curso-angular.jpg" /> <figcaption>Curso online de Angular</figcaption>
</figure>
</a>
</article>
<!-- [...] Aquí se irían repitiendo más elementos <article> con cursos-->
</section>
Y ahora es cuando se va a producir la magia de CSS: con solo una propiedad todo va a cambiar. Nada nuevo por cierto, esta técnica es un viejo conocido que ya hemos tratado en este blog. Se trata de la multicolumna, en este caso indicaremos con la propiedad column-count
que los contenidos se repartan en 3 columnas:
#galeria {
margin: 1rem auto;
width:100%;
max-width:960px;
column-count: 3;
}
Hemos elegido 3 pero podríamos probar con otros valores. Realmente me parece maravilloso el poder cambiar de una sola columna a varias de una forma tan sencilla, únicamente cambiando el valor de una propiedad estándar:
Ahora toca corregir un par de detalles, como el que el título queda demasiado apretado en una sola columna, o que el contenido de los elementos se corta al pasar de una columna a otra:
El título lo vamos a extender a todas las columnas con estas reglas:
-webkit-column-span:all;
column-span:all;
En este caso le indicamos el valor all para que se expanda sobre todas las columnas, pero podríamos poner simplemente el número de columnas sobre las que queremos que se expanda.
Ojo: En Firefox esta regla no funciona, ni siquiera con el prefijo -moz. Las alternativas son, o bien posicionarlo en absoluto, o bien directamente dejarlo fuera del contenedor que vamos a dividir en columnas.
Y para evitar que se nos corten elementos al cambiar de columna usaremos esto:
break-inside: avoid;
page-break-inside: avoid;
La propiedad original de CSS2 es page-break-inside
, que nació para ser usada en las hojas de estilos de impresión. Esta regla evita que, al imprimir una web, al cambiar de página se corten ciertos elementos que nos pueda interesar (por ejemplo, tablas con datos).
Esta propiedad luego ha evolucionado en CSS3 a break-inside: avoid;
pensando en utilizarla también en presentaciones en pantalla para los casos como este, en los que se use la multicolumna.
Recuerda que también podríamos poner un filete (una línea) en el espacio entre columnas para separarlas mejor:
-moz-column-rule: 1px solid #bbb;
-webkit-column-rule: 1px solid #bbb;
column-rule: 1px solid #bbb;
Pero en este caso no lo voy a usar, ya que considero que es más adecuado para contenidos donde predomine el texto. No obstante, dejaré las reglas comentadas en el ejemplo descargable que encontrarás al final del post por si las quieres probar.
Hacemos responsive nuestra galería de imágenes
Y ya lo tenemos, sólo nos faltaría ajustar a nuestro gusto el número de columnas en el comportamiento responsive de la galería, usando las media queries que necesitemos. En este caso las he reducido a 2 columnas para tablets y 1 columna en móviles (más o menos).
/* Móviles en horizontal o tablets en vertical */
@media (max-width: 767px) {
#galeria {
columns:2;
}
}
/* Móviles en vertical */
@media (max-width: 480px) {
#galeria {
columns: 1;
}
}
Y ahora sí, lo tenemos listo. Le he añadido un pequeño efecto de opacidad al pasar el cursor sobre los elementos por motivos estéticos, pero no es necesario usarlo. Puedes descargarte el ejemplo desde aquí.