Skip links

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:

  1. usar display: masonry
  2. usar grid-template-rows: masonry
  3. 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í:

  1. Establecimos grid-auto-rows llegar 0px.
  2. Entonces nos instalamos row-gap llegar 1px.
  3. Luego obtuvimos la altura del proyecto getBoundingClientRect.
  4. Luego damos el tamaño agregando la «asignación de fila» del artículo height este column-gap Valor 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 tarjetas apiladas superpuestas, tres columnas con fondo blanco, bordes circulares negros y texto de marcador de posición generado aleatoriamente.

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')
})
Las tarjetas todavía están apiladas y en tres columnas, pero ahora se apilan más directamente entre sí.

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)}`
  })
}
Un diseño de mampostería alterna entre una columna.

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)}`
  })
}
Tres columnas de diseño de mampostería. La mayoría de los artículos ocupan una columna, pero dos elementos se estiran para ocupar dos columnas. El orden fluye de izquierda a derecha.

¡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».

El primer elemento en el diseño de mampostería contiene una imagen con texto y se encuentra detrás de otros elementos en las dos primeras columnas.

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!

Un diseño de mampostería completo con seis proyectos. El primer y tercer elemento ocupan las dos primeras columnas, y los elementos 2, 4, 5 y 6 fluyen hacia la tercera columna.

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!

Leave a comment

Home
Account
Cart
Search
¡Hola! ¡Pregúntame lo que quieras!
Explore
Drag