soy Kseso y esto EsCSS

Galería de elementos desiguales con distribución uniforme puro Css.

Galería de elementos desiguales con distribución uniforme puro Css.

·Por Kseso ✎ 15

Cómo solucionar sólo con Css el problema de la distribución homogénea y ocupación de todo el espacio en la vertical de cajas con alturas distintas y desconocidas.

Si tenemos una serie de div´s con una imagen y un texto dentro de un contenedor principal tal que así:

<div id="contenedor"> <div id="columnas"> <div class="unidad"> <img src="pic1.jpg" alt="alt" /> <p>Algo de texto sobre la imagen</p> </div> <!-- Nº indeterminado de cajas--> <div class="unidad"> <img src="img2.jpg" alt="alt" /> <p>Texto relativo y descriptivo de la imagen</p> </div> </div>

La distribución homogénea en la horizontal de elementos no reviste mayor problema. Un simple flotado (declarando anchura) es suficiente. El problema surge cuando se desconoce a priori el contenido y este puede variar. Es entonces cuando surgen los problemas. Debido al flujo de los elementos lo normal es que ocurra lo de la imagen:

Nada encaja. Surgen grandes espacios en blanco entre una fila y la siguiente.

Normalmente la solucción pasa por el uso de javascript, hay librerías propias para ello. Pero a costa de calcular en vivo el tamaño de cada uno de los elementos y posicionarlos de forma absoluta.

El resultado sería el de la imagen de abajo y el que vamos a realizar con puro Css:

Solución Css: La propiedad column

Para lograr lo mismo con puro Css tenemos las propiedades column-Propiedad que declaramos en el div padre y a éste lo colocamos dentro de un contenedor general #contenedor sólo a efectos de dar ciertas medidas. De este último podríamos prescindir.

#contenedor { width: 90%; max-width: 1170px; min-width: 800px; margin: 50px auto; } #columnas { column-count: 5; column-gap: 15px; column-fill: auto; }

column-count indica el número de columnas que se generan. column-gap la separación entre ellas y column-fill la forma como se realiza el llenado de cada una, balanceado o no.

Pero con estas propiedades puede surgir un problema. Que la caja que ocupa la posición inferior de una columna reparta su contenido entre ésta y la siguiente. Cuando es texto, no hay mayor quebranto. Pero si son "unidades" compuestas de varios elementos (como el caso que nos ocupa de una imagen y su texto), quedaría feo.

La propiedad column-break-inside

Para evitar el reparto del contenido de un elemento entre dos columnas hay que declarar la propiedad column-break-inside: avoid. Se declara no en el contenedor que crea las columnas sino en los unidades interiores que se apilan en columnas, junto al resto de propiedades para estilizarlo:

.unidad { column-break-inside: avoid; background: #E9EBED; border: 2px solid #FFFFFF; box-shadow: 0 1px 3px rgba(20,20,20, 0.4); display: inline-block; margin: 0 5px 20px; padding: 10px; }

Con lo anterior casi está, sólo tenemos que forzar a las imágenes para que no rompan la estructura y apariencia. Para ello basta con declararles un tamaño:

.unidad img { width: 100%; }

Recuerda que el % no se calcula sobre el tamaño original de la imagen sino sobre la anchura del div que la contiene

Y es todo lo que se necesita para lograrlo. Puedes ver la demo aquí.

Advertencias

En primer lugar el soporte de los navegadores al grupo de las propiedades de las columnas Css3. En la demo sólo incluyo los prefijos -moz- y -webkit-

Otra cuestión es la uniformidad en la parte inferior de las columnas. No quedan a ras.

Y por último, fjate en la numeración que acompaña a cada texto. La ordenación del flujo del html no es de izquierda a derecha. El flujo es de arriba-izquierda hacia abajo hasta completar la 1ª columna para pasar después a la siguiente.

avatar del Editor del blog

the obCSServer ᛯ Ramajero Argonauta, Enredique Amanuense de CSS.
#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Kseso