Hacer diseños de mampostería efectivos hoy
El año pasado, muchos expertos en CSS tuvieron un gran impacto en la posible sintaxis de las nuevas características de diseño de mampostería. tener Dos campamentos principales y Tercer Batallón Esto logra un equilibrio entre los dos:
- usar
display: masonry - usar
grid-template-rows: masonry - usar
item-pack: collapse
No creo que hayan hecho una resolución Sin embargo. Pero es posible que quieras saber Firefox ya admite el diseño de mampostería Use la segunda sintaxis. y Chrome lo está probando Use la primera sintaxis. Si bien es genial ver el soporte nativo en evolución para la mampostería CSS, no podremos usarlo realmente en producción si otros navegadores no admiten la misma implementación …
Entonces, en lugar de agregar mi voz a uno de los campamentos, seguí descubriendo Cómo trabajar con otros navegadores hoy. Me complace informar que encontré una manera y,, ¡recompensas! – Se puede proporcionar soporte Solo 66 líneas de JavaScript.
En este artículo, te mostraré cómo funciona. Pero en primer lugar, esta es una demostración que puedes jugar, solo para demostrar que no soy una mierda. Tenga en cuenta que, dado que estamos esperando que la imagen se cargue primero, habrá algún retraso. Si coloca mampostería en la parte superior, ¡considere omitir la imagen!
De todos modos, aquí está la demostración:
¿Qué tipo de magia es esta?
Ahora hay Una tonelada Incluso si solo hay 66 líneas de JavaScript, incluí esta demostración:
- Puede definir mampostería usando cualquier número de columnas.
- Cada elemento puede abarcar varias columnas.
- Esperamos a que los medios se carguen antes de poder calcular el tamaño de cada elemento.
- Escuchamos
ResizeObserver.
Estos hacen que mi implementación sea muy poderosa, lista para la producción y el uso, y también son más flexibles que muchas personas. Falsificaciones de mampostería flexbox En Internet.
Ahora, un consejo caliente. Si se combina con una variante receptiva del viento de cola y cualquier valor, puede incluir Más flexible Entra en esta malla de mampostería sin escribir más CSS.
Ok, antes de promocionar más, volvamos a la pregunta principal: ¿Cómo funciona esto?
Comencemos con un polyfill
Firefox ha apoyado los diseños de mampostería a través de la sintaxis del segundo batallón. Este es el CSS que necesita para crear un diseño de malla de mampostería CSS en Firefox.
.masonry {
display: grid;
grid-template-columns: repeat(
auto-fit,
minmax(min(var(--item-width, 200px), 100%), 1fr)
);
grid-template-rows: masonry;
grid-auto-flow: dense; /* Optional, but recommended */
}
Dado que Firefox ya tiene soporte de mampostería local, naturalmente, no debemos meterse con él. La mejor manera de verificar si la mampostería es compatible de forma predeterminada es verificar si grid-template-rows Puede mantener masonry valor.
function isMasonrySupported(container) {
return getComputedStyle(container).gridTemplateRows === 'masonry'
}
Si es compatible con la mampostería, omitiremos la implementación. De lo contrario, haremos algo al respecto.
const containers = document.querySelectorAll('.masonry')
containers.forEach(async container => {
if (isMasonrySupported(container)) return
})
El diseño de mampostería lo hace simple
Ahora, quiero tomar este prefacio del segmento de mercado, no soy el que inventó esta tecnología.
Cuando estaba cavando en la red, descubrí esta tecnología y estaba buscando posibles formas de implementar una cuadrícula de mampostería hoy. Entonces, primero desarrolló la idea de desarrolladores desconocidos, tal vez fue mi comprensión, la conversión y uso de ella.
La tecnología se ve así:
- Establecimos
grid-auto-rowsllegar0px. - Entonces nos instalamos
row-gapllegar1px. - Luego obtuvimos la altura del proyecto
getBoundingClientRect. - Luego damos el tamaño agregando la «asignación de fila» del artículo
heightestecolumn-gapValor común.
Esto es real Si ha estado usando CSS Mesh con la forma estándar, no es sensible. Pero una vez que obtienes esto, ¡también puedes dominar cómo funciona!
Ahora, debido a que esto es tan poco intuitivo, vamos a pasar las cosas paso a paso para que pueda ver cómo todo el proceso evoluciona en la salida final.
paso a paso
Primero, nos pusimos grid-auto-rows llegar 0px. Esto es molesto, ya que cada proyecto de cuadrícula tendrá efectivamente una «altura cero». Sin embargo, al mismo tiempo, ¡la cuadrícula CSS mantiene el orden de columnas y filas!
containers.forEach(async container => {
// ...
container.style.gridAutoRows="0px"
})

En segundo lugar, nos instalamos row-gap llegar 1px. Una vez que haga esto, comienza a notar la pila inicial de filas, un píxel debajo de cada píxel.
containers.forEach(async container => {
// ...
container.style.gridAutoRows="0px"
container.style.setProperty('row-gap', '1px', 'important')
})

Tercero, suponiendo que no hay imágenes u otros elementos de medios en el proyecto de la red, podemos obtener fácilmente la altura de cada proyecto de la cuadrícula getBoundingClientRect.
Luego podemos restaurar la «altura» del elemento de la cuadrícula en la cuadrícula CSS reemplazándola grow-row-end y height valor. Esto es porque cada row-gap Ahora 1px Alto.
Cuando hacemos esto, ves que la cuadrícula comienza a formarse. Ahora cada proyecto vuelve a su posición respectiva:
containers.forEach(async container => {
// ...
let items = container.children
layout({ items })
})
function layout({ items }) {
items.forEach(item => {
const ib = item.getBoundingClientRect()
item.style.gridRowEnd = `span ${Math.round(ib.height)}`
})
}

Ahora, necesitamos recuperar la brecha de fila entre los proyectos. Afortunadamente, ya que la malla de mampostería generalmente tiene lo mismo column-gap y row-gap Valor, podemos comprender la brecha de fila requerida leyendo column-gap valor.
Una vez que hacemos esto, lo agregamos a grid-row-end Expanda el número de filas («altura») que el artículo ocupa en la cuadrícula:
containers.forEach(async container => {
// ...
const items = container.children
const colGap = parseFloat(getComputedStyle(container).columnGap)
layout({ items, colGap })
})
function layout({ items, colGap }) {
items.forEach(item => {
const ib = item.getBoundingClientRect()
item.style.gridRowEnd = `span ${Math.round(ib.height + colGap)}`
})
}

¡Y, así, hicimos la cuadrícula de mampostería! Todo aquí es solo para preparar la producción.
Espere a que se carguen los medios
Intente agregar la imagen a cualquier proyecto de cuadrícula y notará que la cuadrícula está desconectada. Eso es porque la altura del artículo será «incorrecta».

Esto está mal porque lo aceptamos height Valores antes de que la imagen se cargue correctamente. El DOM aún no sabe el tamaño de la imagen. Para solucionar esto, debemos esperar a que los medios se carguen antes de que pueda ejecutarse layout Función.
Podemos hacer esto con el siguiente código (no explicaré esto, ya que este no es un truco CSS 😅):
containers.forEach(async container => {
// ...
try {
await Promise.all((areImagesLoaded(container), areVideosLoaded(container)))
} catch(e) {}
// Run the layout function after images are loaded
layout({ items, colGap })
})
// Checks if images are loaded
async function areImagesLoaded(container) {
const images = Array.from(container.querySelectorAll('img'))
const promises = images.map(img => {
return new Promise((resolve, reject) => {
if (img.complete) return resolve()
img.onload = resolve
img.onerror = reject
})
})
return Promise.all(promises)
}
// Checks if videos are loaded
function areVideosLoaded(container) {
const videos = Array.from(container.querySelectorAll('video'))
const promises = videos.map(video => {
return new Promise((resolve, reject) => {
if (video.readyState === 4) return resolve()
video.onloadedmetadata = resolve
video.onerror = reject
})
})
return Promise.all(promises)
}
Mirar¡Tenemos una cuadrícula CSS Masnory que funciona con imágenes y videos!

Haz que responda rápidamente
Este es un paso fácil. Solo necesitamos usar API en reseSoBserver Escuche cualquier cambio en el tamaño del contenedor de cuadrícula de mampostería.
Cuando ocurren cambios, ejecutamos layout Función nuevamente:
containers.forEach(async container => {
// ...
const observer = new ResizeObserver(observerFn)
observer.observe(container)
function observerFn(entries) {
for (const entry of entries) {
layout({colGap, items})
}
}
})
Esta demostración utiliza la API de observador de cambio de tamaño estándar. Pero puedes usar los refinados resizeObserver Funciones que construimos Hace unos días.
containers.forEach(async container => {
// ...
const observer = resizeObserver(container, {
callback () {
layout({colGap, items})
}
})
})
¡Eso es todo! ¡Ahora tiene una poderosa malla de mampostería que puede usar en cada navegador que funcione que admite CSS Mesh!
Emocionante, ¿no? ¡Esta implementación es muy fácil de usar!
Cuadrícula de mampostería y laboratorio brillante
Si no es bueno para usar el código creado por otra persona, tal vez desee considerar Agarra el que construí para ti En Splendid Labz.
Para hacer esto, instale la biblioteca de asistente y agregue el código necesario:
# Installing the library
npm install @splendidlabz/styles
/* Import all layouts code */
@import '@splendidlabz/layouts';
// Use the masonry script
import { masonry } from '@splendidlabz/styles/scripts'
masonry()
Una última cosa: He estado construyendo muchas herramientas para ayudar Haga que sea más fácil para usted y para mí desarrollar la web. Los detendré a todos Excelente laboratorio Brands: uno de estos ejemplos es la cuadrícula de mampostería que le mostré hoy.
Si te gusta esto, puede estar interesado en los demás Utilidad de diseño Esto hace que el diseño sea súper construcción.
Ahora, espero que hayas disfrutado de esta publicación hoy. Si lo desea, libera tu nueva cuadrícula de mampostería CSS y ¡todo va bien!