Echemos un vistazo a una forma superligera de crear un efecto de mampostería horizontal para un conjunto de fotos de tamaño arbitrario. Lanza cualquier conjunto de fotos y se alinearán de borde a borde sin espacios en ninguna parte.
La solución no solo es ligera, sino también bastante sencilla. Usaremos una lista desordenada de imágenes y solo 17 líneas de CSS, siendo los más pesados flexbox
y object-fit
.
¿Por qué?
Tengo dos pasatiempos: documentar mi vida con fotos y descubrir formas interesantes de combinar propiedades CSS, tanto antiguas como nuevas.
Hace un par de semanas, asistí a XOXO y tomé un montón de fotos que reduje a un pequeño y agradable conjunto de 39. Queriendo ser dueño de mi contenido, he pasado los últimos años pensando en armar un blog de fotos simple. , pero nunca pude concretar el diseño que tenía en mente: un diseño de mampostería simple donde las fotos llenan filas respetando su relación de aspecto (piense en Photos.app en iOS, Google Photos, Flickr…).
Investigué un poco para ver si había opciones ligeras que no fueran de JavaScript, pero no pude encontrar nada que se adaptara a mis necesidades. Enfrentándome a algunos vuelos retrasados, comencé a jugar con algún código, limitándome a mantener las cosas lo más simples posible (porque esa es mi definición de diversión).
Marcado básico
Como básicamente estoy creando una lista de imágenes, opté por una lista desordenada:
<ul>
<li>
<img>
</li>
<!-- ... -->
<li>
<img>
</li>
</ul>
Todos granizo flexbox
Luego vino una serie de momentos de bombilla:
- Flexbox es ideal para llenar filas determinando el ancho de la celda en función del contenido de la celda.
- Esto significaba que todas las imágenes (paisaje o retrato) debían tener la misma altura.
- Podría usar
object-fit: cover;
para asegurarse de que las imágenes llenen las celdas.
En teoría, esto sonaba como un plan sólido y me dio un resultado con el que estaba un 90% feliz.
ul {
display: flex;
flex-wrap: wrap;
}
li {
height: 40vh;
flex-grow: 1;
}
img {
max-height: 100%;
min-width: 100%;
object-fit: cover;
vertical-align: bottom;
}
Nota: 40vh
Parecía el mejor enfoque inicial para los navegadores de escritorio, mostrando dos filas completas de fotos en un tamaño razonable e insinuando más a continuación. Esto también permitió más fotos por línea, lo que mejora drásticamente las relaciones de aspecto.
Estiramiento de la última fila
El único problema con el que me encontré es que flexbox realmente quiere llenar todas las líneas, e hizo algunas tonterías con las relaciones de aspecto de las fotos en la última fila. Esta es probablemente mi parte menos favorita de este diseño, pero tuve que agregar un vacío <li>
elemento al final de la lista.
<ul>
<li>
<img>
</li>
<!-- ... -->
<li>
<img>
</li>
<li></li>
</ul>
Combinado con este bit de CSS:
li:last-child {
flex-grow: 10;
}
Nota: No hay ciencia en el uso de “10” aquí. En todas mis pruebas, esto arrojó los mejores resultados.
Manifestación
Ver la pluma
Diseño de fotografía adaptable por Tim Van Damme (@maxvoltar)
en CodePen.
Optimización de la ventana gráfica
Hay algunas consideraciones a tener en cuenta al trabajar en diferentes orientaciones de ventana gráfica.
Retrato
Si su ventana gráfica es más alta que ancha, este enfoque limita la cantidad de fotos por línea, alterando así sus relaciones de aspecto. Para resolver esto, puede hacer que las filas de fotos sean menos altas con esta simple consulta de medios:
@media (max-aspect-ratio: 1/1) {
li {
height: 30vh;
}
}
Pantallas cortas
Para ayudar con dispositivos pequeños en el paisaje, aumentar la altura de las fotos ayuda a verlas lo más grandes posible:
@media (max-height: 480px) {
li {
height: 80vh;
}
}
Pantallas más pequeñas + Retrato
La mayoría de los teléfonos no son lo suficientemente anchos para permitir que flexbox haga su trabajo correctamente sin miniaturizar las fotos, así que aquí opté por no intentar colocar varias fotos por línea. Aún así, vale la pena establecer una altura máxima aquí para que al menos tenga una pista sobre la siguiente foto de la lista.
@media (max-aspect-ratio: 1/1) and (max-width: 480px) {
ul {
flex-direction: row;
}
li {
height: auto;
width: 100%;
}
img {
width: 100%;
max-height: 75vh;
min-width: 0;
}
}
¡Ahí lo tenemos!
Este enfoque no respeta completamente las relaciones de aspecto de las fotos (pero está cerca) y ocasionalmente conduce a algunos resultados extraños, pero me encanta la simplicidad y flexibilidad de todo. ¿Quieres que tu galería se desplace horizontalmente en lugar de verticalmente? Un par de ajustes te permitirán hacer esto. ¿Hay 1000 fotos en la galería o solo una? Todo se verá bien. ¿No tienes claro las relaciones de aspecto? Flexbox es tu mejor amigo. ¡Eche otro vistazo a la demostración si aún no lo ha hecho, y déjeme saber lo que piensa!
Prima
Dependiendo del tamaño de estas fotos, una página como esta puede crecer rápidamente a varios megabytes. En el blog en el que estoy trabajando, agregué loading="lazy"
para ayudar con esto. Con ese atributo en su lugar en las imágenes, solo carga las fotos una vez que te acercas a ellas mientras te desplazas. Es compatible solo en Chrome por ahora, pero podría implementar su propia técnica más compatible.