Comentarios necesarios: ¿Cómo debemos definir la mampostería de CSS?

Ian Kilpatrick
Ian Kilpatrick
Tab Atkins-Bittner
Tab Atkins-Bittner

Fecha de publicación: 19 de septiembre de 2024

El grupo de trabajo de CSS combinó las dos propuestas de muratura de CSS en un borrador de especificación. El grupo espera que esto facilitará la comparación de los dos y la toma de una decisión final. El equipo de Chrome aún cree que una sintaxis de masonry independiente sería la mejor manera de proceder. Si bien se resolvió el mayor problema de rendimiento que se mencionó en nuestra publicación anterior, aún existen inquietudes en cuanto a la sintaxis, los valores iniciales y la facilidad con la que se podría aprender una versión combinada con la cuadrícula.

Sin embargo, para probar nuestras suposiciones, trabajamos con algunos ejemplos para mostrar cómo funcionaría el diseño de cuadrícula con cada versión. Consulta los ejemplos de esta publicación y envíanos tus comentarios para que podamos tomar una decisión y continuar con esta función.

Esta publicación no abarca todos los casos de uso posibles, pero está claro que separar la disposición en filas del diseño de cuadrícula no hará que la función carezca de funcionalidad. De hecho, es posible que lo opuesto sea cierto. Como verás en esta publicación, la versión display: masonry crea nuevas oportunidades y una sintaxis más simple. Además, muchos desarrolladores expresaron su preocupación por el hecho de que la posibilidad de volver a ordenar elementos con el diseño de masonry cause problemas de accesibilidad. Esto también se está tratando para ambas versiones de la sintaxis, a través de la propiedad reading-flow propuesta.

Un diseño de mampostería básico

Este es el diseño que la mayoría de las personas imaginan cuando piensan en la mampostería. Los elementos se muestran en filas y, después de colocar la primera fila, los elementos posteriores se mueven al espacio que dejan los elementos más cortos.

Un diseño con columnas, en el que los elementos que ocupan las columnas lo hacen sin espacios.
En este diseño, se definen las columnas y, luego, los elementos se completan con una disposición en filas en lugar de filas estrictas.

Con display: masonry

Para crear un diseño de mampostería, usa el valor de masonry para la propiedad display. Esto crea un diseño de mampostería con segmentos de columna que tú defines (o que define el contenido) y mampostería en el otro eje. El primer elemento se muestra en el bloque y al principio intercalado (por lo tanto, en la parte superior izquierda en inglés), y los elementos se organizan en la dirección intercalada.

Para definir pistas, usa masonry-template-tracks con los valores de la lista de pistas como se usa en el diseño de cuadrícula de CSS.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(3, 1fr);
  gap: 10px;
}

Con display: grid

Para crear un diseño de mampostería, primero crea un diseño de cuadrícula con el valor de grid para la propiedad display. Define las columnas con la propiedad grid-template-columns y, luego, asígnale a grid-template-rows un valor de masonry.

Esto creará un diseño como lo esperas con los elementos de cuadrícula colocados automáticamente. Sin embargo, los elementos de cada fila usan un diseño de mampostería y se reorganizarán para ocupar el espacio que dejan los elementos más pequeños en la fila anterior.

.masonry {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: masonry;
  gap: 10px;
}

Aspectos que debes tener en cuenta entre las dos opciones

Una diferencia notable entre estos métodos es que, con la versión display: masonry, obtienes un diseño de mampostería, incluso si no especificas ningún segmento con masonry-template-tracks. Por lo tanto, display: masonry podría ser todo lo que necesitas. Esto se debe a que el valor inicial de masonry-template-tracks es repeat(auto-areas, auto). El diseño crea tantas pistas de tamaño automático como se ajusten al contenedor.

Flujo invertido con mampostería

La especificación incluye formas de cambiar la dirección del flujo de la maqueta. Por ejemplo, puedes cambiar el flujo para que se muestre desde el final del bloque hacia arriba.

Un diseño con columnas, en el que los elementos que ocupan las columnas lo hacen desde la parte inferior del diseño.
En este diseño, se definen las columnas y, luego, los elementos se completan con la técnica de construcción de muros a partir del final del bloque.

Con display: masonry

Crea un diseño de mampostería con display: masonry y, luego, usa masonry-direction con un valor de column-reverse.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(3, 1fr);
  masonry-direction: column-reverse;
}

Con display: grid

Crea un diseño de mampostería con display: grid y grid-template-rows: masonry. Luego, usa la propiedad grid-auto-flow con un valor nuevo de row-reverse para que los elementos se diseñen desde el extremo del bloque del contenedor de cuadrícula.

.masonry {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: masonry;
  grid-auto-flow: row-reverse;
}

Aspectos que debes tener en cuenta entre las dos opciones

La versión display: masonry se siente muy similar a cómo funciona flexbox. Cambia la dirección en la que fluyen las columnas con la propiedad masonry-direction con un valor de column-reverse.

La versión de cuadrícula de CSS usa grid-auto-flow. Según la definición actual, grid-auto-flow: row-reverse y grid-auto-flow: column-reverse tendrían el mismo efecto. Esto puede ser confuso, ya que es posible que esperes que hagan algo diferente.

Disposición en filas

También puedes cambiar la dirección para definir filas.

Un diseño con filas, en el que los elementos que ocupan las filas lo hacen sin espacios.
En este diseño, se definen las filas y, luego, los elementos se completan con una disposición en filas en lugar de columnas estrictas.

Con display: masonry

Crea un diseño de mampostería con display: masonry y, luego, establece el valor de masonry-direction en row. A menos que quieras que tus filas tengan un tamaño de bloque específico, no es necesario que especifiques el tamaño de las pistas, ya que el valor predeterminado es auto, por lo que el tamaño de las pistas se ajustará al contenido que contengan.

.masonry {
  display: masonry;
  masonry-direction: row;
}

Con display: grid

.masonry {
  display: grid;
  grid-template-columns: masonry;
  grid-template-rows: repeat(3, 1fr);
}

Aspectos que debes tener en cuenta entre las dos opciones

Al igual que con el flujo invertido, cambiar la versión de display: masonry de columnas a filas significa cambiar el valor de masonry-direction. Con la versión de cuadrícula, deberás cambiar los valores de las propiedades grid-template-columns y grid-template-rows. O bien, si usas la abreviatura, cambia el orden de la sintaxis.

Con ambos ejemplos de flujo de cambio, la versión de display: masonry se siente más intuitiva. Hay una sola propiedad que controla el flujo masonry-direction, que toma uno de los siguientes valores:

  • row
  • column
  • row-reverse
  • column-reverse

Luego, agregas la información de tamaño necesaria a masonry-template-tracks, siempre que el valor automático predeterminado no sea lo que necesitas.

Con la cuadrícula, para hacer la dirección inversa, debes usar la propiedad grid-auto-flow y, para hacer la muratura de filas, cambia el valor de las propiedades grid-template-*. Tampoco es posible, en la sintaxis de cuadrícula actual, dejar indefinido el valor del eje de cuadrícula. Siempre debes especificar propiedades grid-template-* en el eje que no tenga un valor de masonry.

Cómo posicionar elementos

En ambas versiones, puedes posicionar elementos de forma explícita con la posición basada en líneas que ya conoces del diseño de cuadrícula. En ambas versiones, solo puedes posicionar elementos en el eje de la cuadrícula, que es el eje con los segmentos predefinidos. No puedes posicionar elementos en el eje que está haciendo el diseño de mampostería.

Con display: masonry

El siguiente CSS define un diseño de mampostería con cuatro columnas. Por lo tanto, el eje de la cuadrícula es columnas. El elemento con una clase de a se coloca desde la primera línea de la columna hasta la tercera línea de la columna, abarcando dos segmentos con las nuevas propiedades masonry-track-*. Esto también se puede definir como una abreviatura de masonry-track: 1 / 3;.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(4, 1fr);
}

.a {
  masonry-track-start: 1;
  masonry-track-end: 3;
}

Con display: grid

El siguiente CSS define un diseño de mampostería con cuatro columnas. Por lo tanto, el eje de la cuadrícula es columnas. El elemento con una clase de a se coloca desde la primera línea de la columna hasta la tercera línea de la columna, abarcando dos segmentos con las propiedades grid-column-*. Esto también se puede definir como un atajo de grid-column: 1 / 3;.

Si el eje de la cuadrícula es columnas, se ignorarán las propiedades grid-row-* y, si el eje de la cuadrícula es filas, se ignorarán las propiedades grid-columns-*.

.masonry {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}

.a {
  grid-column-start: 1;
  grid-column-end: 3;
}

Puedes usar líneas con nombre con ambos sintaxis. En los siguientes ejemplos, se muestra una cuadrícula con dos líneas de columna llamadas a.

Con display: masonry

Las líneas con nombre se definen en el valor de la lista de pistas de masonry-template-tracks. El elemento se puede colocar después de cualquier línea llamada a.

.masonry {
  display: masonry;
  masonry-template-tracks: 100px [a] auto [a] auto 100px;
}

.item {
  masonry-track: a;
}

Con display: grid

Las líneas con nombre se definen en el valor de la lista de pistas de grid-template-columns. El elemento se coloca después de la primera línea llamada a. Si se define la propiedad grid-row, se ignorará.

.masonry {
  display: grid;
  grid-template-columns: 100px [a] auto [a] auto 100px;
  grid-template-rows: masonry;
}

.item {
  grid-column: a;
  grid-row: a; /* ignored */
}

También puedes usar áreas con nombre en ambos sintaxis. En los siguientes ejemplos, se muestra una cuadrícula con tres segmentos denominados "a", "b" y "c".

Con display: masonry

Los segmentos se nombran como el valor de masonry-template-areas. Como no se definen tamaños de segmentos, los tres tienen el tamaño auto de forma predeterminada. El elemento se coloca en la pista “a”.

.masonry {
  display: masonry;
  masonry-template-areas: "a b c";
}

.item {
  masonry-track: a;
}

Esto funciona de la misma manera, ya sea que definas filas o columnas. La única diferencia sería la propiedad masonry-direction.

Con display: grid

En el caso de las columnas, la sintaxis es esencialmente idéntica. Del mismo modo, como no se definen tamaños de segmentos, los tres tienen el tamaño auto de forma predeterminada, pero aún debes indicar de forma explícita que el otro eje es de tipo masonry:

.masonry {
  display: grid;
  grid-template-areas: "a b c";
  grid-template-rows: masonry;
}

.item {
  grid-column: a;
}

Sin embargo, en el caso de las filas, el valor se debe escribir de manera diferente, ya que grid-template-areas en realidad define un área de dos dimensiones, y cada fila se escribe como una cadena independiente:

.masonry {
  display: grid;
  grid-template-areas: "a" "b" "c"; /* Note the difference, each row is quoted. */
  grid-template-columns: masonry;
}

.item {
  grid-row: a;
}

Aspectos que debes tener en cuenta entre las dos opciones

Con cualquier posicionamiento, la sintaxis display: masonry funciona mejor cuando se trata de cambiar de dirección. Como la propiedad masonry-track-* funciona en cualquier dirección que sea el eje de la cuadrícula, todo lo que debes hacer para cambiar de dirección es cambiar el valor de masonry-direction. Con la versión de cuadrícula, al menos necesitarás propiedades redundantes para habilitar el cambio. Sin embargo, consulta los ejemplos anteriores para ver otras formas en las que cambiar de dirección es más complicado con la versión de cuadrícula.

Símbolos abreviados

En esta publicación, se usaron las formas largas para aclarar qué propiedades están en uso. Sin embargo, las versiones display: masonry y display: grid se pueden definir con abreviaturas.

Con display: masonry

La abreviatura display: masonry usa la palabra clave masonry. Para crear el diseño básico de galería, usa el siguiente CSS:

.masonry {
  display: masonry;
  masonry: repeat(3, 1fr);
}

Para crear un diseño de maqueta simple basado en filas, haz lo siguiente:

.masonry {
  display: masonry;
  masonry: row;
}

Para definir segmentos y un diseño basado en filas con la abreviatura, haz lo siguiente:

.masonry {
  display: masonry;
  masonry: repeat(3, 1fr) row;
}

Con display: grid

Para crear el diseño básico de mampostería con la abreviatura grid.

.masonry {
  display: grid;
  grid: masonry / repeat(3, 1fr);
}

Para crear un diseño de maqueta simple basado en filas, haz lo siguiente:

.masonry {
  display: grid;
  grid: repeat(3, auto) / masonry;
}

En ejemplos más complejos, como la sintaxis general de display:masonry es más simple, se pueden agrupar más propiedades en la abreviatura sin que se vuelva demasiado compleja.

Por ejemplo, imagina que creas tres columnas, llamadas “a”, “b” y “c”, que se completan de abajo hacia arriba.

Con display:masonry

En display: masonry, los tres se pueden configurar juntos en la abreviatura:

.masonry {
  display: masonry;
  masonry: column-reverse "a b c";
}

Como el tamaño se ajusta automáticamente, no es necesario que especifiques los tamaños, pero si prefieres un tamaño específico, puedes agregarlo. Por ejemplo: masonry: column-reverse 50px 100px 200px "a b c";

Además, cada componente se puede reordenar libremente, no hay un orden específico que necesites recordar. Y si, en cambio, quieres hacer filas, todo lo que debes hacer es intercambiar column-reverse por row o row-reverse. El resto de la sintaxis sigue siendo el mismo.

Con display: grid

En display: grid, estos tres aspectos se deben configurar por separado:

.masonry {
  display: grid;
  grid-template-rows: masonry;
  grid-template-areas: "a b c";
  grid-auto-flow: wrap-reverse;
}

Al igual que en el ejemplo de la disposición en mosaico, esto hace que todas las columnas tengan el tamaño auto, pero si quieres proporcionar tamaños explícitos, puedes hacerlo de la siguiente manera:

.masonry {
  display: grid;
  grid: masonry / 50px 100px 200px;
  grid-template-areas: "a b c";
  grid-auto-flow: wrap-reverse;
}

O bien, si quieres usar "grid" para establecer los tamaños y los nombres de las áreas todos juntos, haz lo siguiente:

.masonry {
  display: grid;
  grid: "a b c" masonry / 50px 100px 200px;
  grid-auto-flow: wrap-reverse;
}

En ambos ejemplos, el orden es estrictamente obligatorio y es diferente si quieres filas. Por ejemplo, cambiar a filas se ve de la siguiente manera:

.masonry {
  display: grid;
  grid: 50px 100px 200px / masonry;
  grid-template-areas: "a" "b" "c";
}

O bien, para reunirlos en una sola abreviatura:

.masonry {
  display: grid;
  grid: "a" 50px "b" 100px "c"  200px / masonry;
}

Aspectos que debes tener en cuenta entre las dos opciones

Es probable que la abreviatura display: masonry se use mucho, ya que es una sigla relativamente sencilla. En muchos casos, para un diseño de muratura “estándar”, solo debes configurar las definiciones de segmentos. Todos los demás valores pueden asumir la configuración predeterminada.

La versión display: grid usa la sigla existente grid, que es bastante compleja y, en nuestra experiencia, los desarrolladores la usan con menos frecuencia. Como se muestra en los ejemplos anteriores, incluso cuando se usa para diseños de mampostería simples, se debe tener cuidado cuando se establece el orden de los valores.

Otras consideraciones

En esta publicación, se analizan algunos casos de uso comunes en la actualidad. Sin embargo, no sabemos qué nos depara el futuro para la cuadrícula o la mampostería. Un gran argumento para usar la sintaxis display: masonry separada es que permite que ambas diverjan en el futuro. En particular, con los valores iniciales, como los de masonry-template-tracks, puede ser útil hacer algo diferente en la disposición en filas que en la cuadrícula. No podemos cambiar los valores predeterminados de la cuadrícula si elegimos la versión display: grid, lo que podría limitar las acciones que podríamos querer realizar en el futuro.

En estos ejemplos, puedes ver lugares en los que el navegador debe ignorar las propiedades que son válidas en la cuadrícula si usas el diseño de mampostería. Por ejemplo, grid-template-areas, en el que la mayoría de los valores se descartan, ya que define un diseño de cuadrícula de dos dimensiones. En la mampostería, solo definimos una dirección por completo.

Envía tus comentarios

Observa estos ejemplos y también el borrador de la especificación que presenta cada versión junto con la otra. Para darnos tu opinión, comenta el problema 9041 o, si prefieres escribir una publicación en tu propio blog o en redes sociales, asegúrate de informarnos en X o LinkedIn.