Diseño de mampostería solo para CSS

Necesito implementar un diseño de mampostería bastante deteriorado. Sin embargo, por varias razones no quiero usar JavaScript para hacerlo.

Una cuadrícula de múltiples columnas de rectángulos de altura variable.

Parámetros:

  • Todos los elementos tienen el mismo ancho.
  • Los elementos tienen una altura que no se puede calcular del lado del servidor (una imagen más varias cantidades de texto)
  • Puedo vivir con un número fijo de columnas si tengo que

Hay una solución trivial a esto que funciona en los navegadores modernos, la propiedad de column-count .

El problema con esa solución es que los elementos se ordenan en columnas:

Comenzando desde el cuadro superior izquierdo, están numerados del 1 al 4 en línea recta, el cuadro superior de la siguiente columna es 5, y así sucesivamente.

Si bien necesito que los elementos se ordenen en filas, al menos aproximadamente:

Comenzando desde el cuadro superior izquierdo, están numerados del 1 al 6 en línea recta, pero como el cuadro 5 es el más corto, el cuadro que está debajo es el 7, ya que parece estar en una fila más alta que el cuadro siguiente en el extremo izquierdo.

Enfoques que he intentado que no funcionan:

  • display: inline-block elementos display: inline-block : desperdicio de espacio vertical.
  • Haciendo float: left artículos float: left : jajaja, no.

Ahora podría cambiar la representación del lado del servidor y reordenar los elementos dividiendo el número de elementos por el número de columnas, pero eso es complicado, propenso a errores (según la forma en que los navegadores deciden dividir la lista de elementos en columnas), así que me gustaría para evitarlo si es posible.

¿Hay alguna magia de flexbox novedosa que haga esto posible?

Flexbox

Un diseño dynamic de mampostería no es posible con flexbox, al menos no de una manera limpia y eficiente.

Flexbox es un sistema de diseño unidimensional. Esto significa que puede alinear elementos a lo largo de líneas horizontales o verticales. Un elemento flexible se limita a su fila o columna.

Un verdadero sistema de cuadrícula es bidimensional, lo que significa que puede alinear elementos a lo largo de líneas horizontales Y verticales. Los elementos de contenido pueden abarcar filas y columnas simultáneamente, lo que los elementos flexibles no pueden hacer.

Es por esto que flexbox tiene una capacidad limitada para construir grillas. También es una razón por la que el W3C ha desarrollado otra tecnología CSS3, Grid Layout .


row wrap

En un contenedor flex-flow: row wrap , los elementos flexibles deben envolverse en filas nuevas.

Esto significa que un elemento flexible no puede ajustarse bajo otro elemento en la misma fila .

Fíjese en cómo div # 3 se ajusta debajo de div # 1 , creando una nueva fila. No puede envolverse debajo de div # 2 .

Como resultado, cuando los elementos no son los más altos en la fila, el espacio en blanco permanece, creando brechas antiestéticas.


column wrap

Si cambia a flex-flow: column wrap , se puede obtener un diseño similar a una cuadrícula. Sin embargo, un contenedor de dirección de columna tiene cuatro problemas potenciales desde el principio:

  1. Los elementos flexibles fluyen verticalmente, no horizontalmente (como usted necesita en este caso).
  2. El contenedor se expande horizontalmente, no verticalmente (como el diseño de Pinterest).
  3. Requiere que el contenedor tenga una altura fija, por lo que los elementos saben dónde envolver.
  4. A partir de este escrito, tiene una deficiencia en todos los navegadores principales donde el contenedor no se expande para acomodar columnas adicionales .

Como resultado, un contenedor de dirección de columna no es una opción en este caso, y en muchos otros casos.


CSS Grid con dimensiones de elemento indefinido

El diseño de cuadrícula sería una solución perfecta para su problema si las distintas alturas de los elementos de contenido pudieran ser predeterminadas . Todos los demás requisitos están bien dentro de la capacidad de Grid.

El ancho y la altura de los elementos de la cuadrícula se deben conocer para cerrar las brechas con los elementos circundantes.

Entonces, Grid, que es lo mejor que CSS tiene para ofrecer para construir un diseño de mampostería que fluye horizontalmente, se queda corto en este caso.

De hecho, hasta que llegue una tecnología CSS con la capacidad de cerrar las brechas automáticamente, CSS en general no tiene solución. Algo como esto probablemente requiera volver a ver el documento, así que no estoy seguro de qué tan útil o eficiente sería.

Necesitarás un guión.

Las soluciones de JavaScript tienden a utilizar el posicionamiento absoluto, que elimina elementos de contenido del flujo de documentos para reorganizarlos sin espacios. Aquí hay dos ejemplos:

  • Desandro Masoneria

    La albañilería es una biblioteca de diseño de cuadrícula de JavaScript. Funciona al colocar los elementos en una posición óptima en función del espacio vertical disponible, algo así como una piedra de albañil en una pared.

    fuente: http://masonry.desandro.com/

  • Cómo construir un sitio que funcione como Pinterest

    [Pinterest] realmente es un sitio genial, pero lo que me parece interesante es cómo están diseñados estos tablones de anuncios … Entonces, el propósito de este tutorial es recrear nosotros mismos este efecto de bloque de respuesta …

    fuente: https://benholland.me/javascript/2012/02/20/how-to-build-a-site-that-works-like-pinterest.html


CSS Grid con dimensiones de artículo definidas

Para diseños donde se conoce el ancho y el alto de los elementos de contenido, aquí hay un diseño de mampostería que fluye horizontalmente en CSS puro:

 grid-container { display: grid; /* 1 */ grid-auto-rows: 50px; /* 2 */ grid-gap: 10px; /* 3 */ grid-template-columns: repeat(auto-fill, minmax(30%, 1fr)); /* 4 */ } [short] { grid-row: span 1; /* 5 */ background-color: green; } [tall] { grid-row: span 2; background-color: crimson; } [taller] { grid-row: span 3; background-color: blue; } [tallest] { grid-row: span 4; background-color: gray; } grid-item { display: flex; align-items: center; justify-content: center; font-size: 1.3em; font-weight: bold; color: white; } 
  01 02 03 04 05 06 07 08 09 10 etc.