Logotipo de Zephyrnet

Cuadrícula CSS y formas personalizadas, parte 3

Fecha:

Después Parte 1 y Parte 2, Estoy de regreso con un tercer artículo para explorar formas más elegantes. Al igual que en los artículos anteriores, vamos a combinar CSS Grid con recorte y enmascaramiento para crear diseños elegantes para galerías de imágenes.

Serie CSS Grid y formas personalizadas

¿Debo leer los artículos anteriores antes?

No es obligatorio, pero sí muy recomendable cubrir tantos trucos como sea posible. También puede leerlos en cualquier orden, pero seguirlos en orden cronológico es una buena idea para ver cómo llegamos aquí.

Basta de hablar, pasemos directamente a nuestro primer ejemplo.

Antes de profundizar en el CSS, revisemos el marcado:

Nada más que unos pocos etiquetas en un contenedor div, ¿verdad? Recuerde, el principal desafío de esta serie es trabajar con la menor cantidad de HTML posible. Todos los ejemplos que hemos visto a lo largo de esta serie usan exactamente el mismo marcado HTML. Sin divs adicionales, envoltorios y demás. Todo lo que necesitamos son imágenes contenidas en un elemento contenedor.

Revisemos el CSS ahora:

.gallery {
  --g: 6px; /* the gap */

  display: grid;
  width: 450px; /* the size */
  aspect-ratio: 1; /* equal height */
  grid: auto-flow 1fr / repeat(3, 1fr);
  gap: var(--g);
}
.gallery img:nth-child(2) {
  grid-area: 1 / 2 / span 2 / span 2;
}
.gallery img:nth-child(3) {
  grid-area: 2 / 1 / span 2 / span 2;
}

Básicamente, esta es una cuadrícula cuadrada con tres columnas iguales. A partir de ahí, todo lo que sucede es que la segunda y la tercera imagen se colocan explícitamente en la cuadrícula, lo que permite que la primera y la última imagen se distribuyan automáticamente a su alrededor.

Este comportamiento automático es una característica poderosa de CSS Grid llamada "ubicación automática". Lo mismo con el número de filas: ninguna de ellas está definida explícitamente. El navegador los crea "implícitamente" en función de la ubicación de los elementos. tengo un artículo muy detallado que explora ambos conceptos.

Tal vez se pregunte qué está pasando con esos grid y grid-area valores de propiedad. ¡Se ven extraños y son difíciles de asimilar! Eso es porque elegí el CSS grid propiedad abreviada, que es súper útil pero acepta una cantidad indecorosa de valores de sus propiedades constituyentes. Puedes verlos todos en el almanaque.

Pero lo que realmente necesitas saber es esto:

grid: auto-flow 1fr / repeat(3, 1fr);

… es equivalente a esto:

grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 1fr;
Reglas de estilo de DevTools para la propiedad de cuadrícula.
También puede usar sus DevTools favoritas para obtener más pruebas.

Lo mismo para el grid-area propiedad. Si abrimos DevTools e inspeccionamos nuestra declaración: grid-area: 1/2/span 2/span 2; obtendrá lo siguiente:

grid-area: 1 / 2 / span 2 / span 2;

…eso es lo mismo que escribir todo esto:

grid-row-start: 1; /* 1st row */
grid-column-start: 2; /* 2nd column */
grid-row-end: span 2; /* take 2 rows */
grid-column-end: span 2; /* take 2 columns */

Mismo trato para el otro grid-area declaración. Cuando ponemos todo junto, esto es lo que obtenemos:

Sí, la segunda y la tercera imagen se superponen en el medio. ¡Eso no es un error! Los coloqué a propósito uno encima del otro para poder aplicar un clip-path para cortar una porción de cada uno y obtener el resultado final:

Mostrando el efecto con y sin clip-path.

¿Como hacemos eso? Podemos cortar la esquina inferior izquierda de la segunda imagen (img:nth-child(2)) con el CSS clip-path propiedad:

clip-path: polygon(0 0, 100% 0, 100% 100%, calc(50% + var(--g) / 4) 100%, 0 calc(50% - var(--g) / 4))

Y la esquina superior derecha de la tercera:

clip-path: polygon(0 0, calc(50% - var(--g) / 4) 0, 100% calc(50% + var(--g) / 4), 100% 100%, 0 100%);

Sé que sé. Eso es un montón de números y todo eso. Yo tengo un artículo que detalla la técnica.

Eso es todo, ¡tenemos nuestra primera grilla de imágenes! Agregué una escala de grises filter en Selector para obtener ese pequeño efecto de desplazamiento.

Revelación de imagen dividida

Probemos algo diferente. Podemos tomar lo que aprendimos sobre recortar la esquina de una imagen y combinarlo con un bonito efecto para revelar la imagen completa al pasar el mouse por encima.

La configuración de cuadrícula para este es menos intensa que la anterior, ya que todo lo que necesitamos son dos imágenes superpuestas:

.gallery {
  display: grid;
}
.gallery > img {
  grid-area: 1 / 1;
  width: 350px; /* the size */
  aspect-ratio: 1; /* equal height */
}

Dos imágenes del mismo tamaño se apilan una encima de la otra (gracias a grid-area: 1 / 1).

El efecto de desplazamiento se basa en animar clip-path. Analizaremos el código de la primera imagen para ver cómo funciona, luego conectaremos lo mismo en la segunda imagen con valores actualizados. Tenga en cuenta, sin embargo, que tenemos tres estados diferentes:

  1. Cuando no se desplaza ninguna imagen, se revela la mitad de cada imagen.
  2. Cuando pasamos el mouse sobre la primera imagen, se revela más completamente pero conserva un pequeño clip de esquina.
  3. Cuando pasamos el cursor sobre la segunda imagen, la primera tiene solo un pequeño triángulo visible.
Mostrando los tres estados de recorte del efecto de desplazamiento.

En cada caso, tenemos una forma triangular. Eso significa que necesitamos un polígono de tres puntos para el clip-path .

¿Qué? El segundo estado no es un triángulo, sino más bien un cuadrado con una esquina recortada.

Tienes razón, pero si nos fijamos bien podemos ver un triángulo “oculto”. Agreguemos un box-shadow a las imágenes.

¡Ajá! ¿Lo notaste?

Mostrando la transición entre estados con la forma de desbordamiento revelada para explicar cómo funciona.

¿Qué clase de magia es esta? Es un hecho poco conocido que clip-path acepta valores fuera del 0%-100% gama, que nos permite crear formas “desbordantes”. (Sí, acabo de acuñar esto. De nada). De esta manera, solo tenemos que trabajar con tres puntos en lugar de los cinco que se necesitarían para hacer la misma forma a partir de las partes visibles. ¡CSS optimizado para ganar!

Este es el código después de que insertamos los valores del polígono en el clip-path propiedad:

.gallery > img:first-child {
  clip-path: polygon(0 0, calc(100% + var(--_p)) 0 , 0 calc(100% + var(--_p)))
}
.gallery > img:last-child {
  clip-path: polygon(100% 100%, 100% calc(0% - var(--_p)), calc(0% - var(--_p)) 100%)
}

Note la --_p variable. Estoy usando eso para optimizar un poco el código a medida que agregamos la transición de desplazamiento. En lugar de actualizar todo clip-path solo actualizamos esta variable para obtener el movimiento. Aquí hay un video para ver cómo deben moverse los puntos entre cada estado:

Podemos dar una bofetada transition en selector, luego actualice el --_p variable en los estados para obtener el efecto final:

.gallery {
  --g: 8px; /* the gap */
}
.gallery > img {
  /* etc. */
  --_p: calc(-1 * var(--g));
  transition: .4s .1s;
}
.gallery:hover > img:last-child,
.gallery:hover > img:first-child:hover{
  --_p: calc(50% - var(--g));
}
.gallery:hover > img:first-child,
.gallery:hover > img:first-child:hover + img {
  --_p: calc(-50% - var(--g));
}

Si no consideramos la brecha (definida como --g en el código) entre las imágenes, entonces los tres valores de --_p en 0%, 50%y -50%. Cada uno define uno de los estados que explicamos anteriormente.

Revelación de la imagen del pastel

Aumentemos el nivel de dificultad de este último e intentemos hacer el mismo truco pero con cuatro imágenes en lugar de dos.

¿Guay, verdad? Cada imagen es un cuarto de círculo y, al pasar el mouse, tenemos una animación que transforma una imagen en un círculo completo que cubre las imágenes restantes. El efecto puede parecer imposible porque no hay forma de rotar puntos y transformarlos para llenar el círculo. En realidad, sin embargo, no estamos rotando ningún punto en absoluto. ¡Es una ilusión!

Para este ejemplo, sólo me centraré en el clip-path animación ya que la configuración de la cuadrícula es la misma que en el ejemplo anterior: cuatro imágenes del mismo tamaño apiladas una encima de la otra.

Y un video digno de una aburrida y larga explicación:

La clip-path está formado por siete puntos, donde tres de ellos están en una posición fija y los otros se mueven como se muestra en el video. El efecto se ve menos genial cuando se ejecuta lentamente, pero podemos ver cómo el clip-path se transforma entre formas.

El efecto es un poco mejor si le agregamos border-radius y lo hacemos más rápido:

Y al hacerlo aún más rápido como en el ejemplo original, obtenemos la ilusión perfecta de un cuarto de círculo transformándose en un círculo completo. Aquí está el valor del polígono para nuestro clip-path en la primera imagen de la secuencia:

.gallery > img:nth-child(1) {
  clip-path: polygon(50% 50%, calc(50% * var(--_i, 0)) calc(120% * var(--_i, 0)), 0 calc(100% * var(--_i, 0)),0 0, 100% 0, 100% calc(100% * var(--_i, 0)), calc(100% - 50% * var(--_i, 0)) calc(120% * var(--_i, 0)));
}
.gallery > img:hover {
 --_i: 1;
}

Como de costumbre, estoy usando una variable para optimizar el código. La variable cambiará entre 0 y 1 para actualizar el polígono.

Lo mismo ocurre con la imagen de los demás pero con una diferente clip-path configuración. Sé que los valores pueden parecer difíciles de descifrar, pero siempre puedes usar herramientas en línea como Clippy para visualizar los valores.

El mosaico de las imágenes

Conoces los mosaicos, ¿verdad? Es un estilo de arte que crea diseños decorativos a partir de piezas individuales más pequeñas, como piedras de colores. Pero también puede ser una imagen compuesta formada por otras imágenes más pequeñas.

Y, lo adivinaste: ¡podemos hacer ese tipo de cosas en CSS!

Primero, imaginemos cómo serían las cosas si clip-path fueron sacados de la mezcla y todo lo que teníamos eran cinco imágenes superpuestas:

Estoy haciendo un poco de trampa en este video porque estoy inspeccionando el código para identificar el área de cada imagen, pero esto es lo que debes hacer en tu cabeza. Para cada imagen, intenta completar la parte que falta para ver el rectángulo completo y, con esto, podemos identificar la posición y el tamaño de cada uno.

Necesitamos encontrar cuántas columnas y filas necesitamos para la cuadrícula:

  1. Tenemos dos imágenes grandes colocadas una al lado de la otra, cada una de las cuales ocupa la mitad del ancho de la cuadrícula y la altura completa de la cuadrícula. Eso significa que probablemente necesitará Dos columnas (uno para ambas imágenes) y una fila (para toda la altura de la rejilla).
  2. Tenemos la imagen en el medio que se superpone a las otras dos imágenes. Eso significa que realmente necesitamos cuatro columnas en lugar de dos, aunque todavía solo necesitamos el una fila.
  3. Cada una de las dos últimas imágenes llena la mitad de la cuadrícula, al igual que las dos primeras imágenes. Pero son sólo la mitad de la altura de la cuadrícula. Podemos usar las columnas existentes que ya tenemos, pero vamos a necesitar dos filas en lugar de uno para tener en cuenta que estas imágenes tienen la mitad de la altura de la cuadrícula.
Eso nos deja con una cuadrícula ordenada de 4 × 2.

No quiero que pienses que la forma en que corté esto es la , solamente manera de hacerlo Así es simplemente como le he dado sentido. ¡Estoy seguro de que hay otras configuraciones posibles para obtener el mismo diseño!

Tomemos esa información y definamos nuestra cuadrícula, luego coloquemos las imágenes en ella:

.gallery {
  display: grid;
  grid: repeat(2, 1fr) / repeat(4, 1fr); 
  aspect-ratio: 2;
}
.gallery img:nth-child(1) {
  grid-area: 1 / 1 / span 2 / span 2;
}
.gallery img:nth-child(2) {
  grid-area: 1 / 2 / span 2 / span 2;
}
.gallery img:nth-child(3) {
  grid-area: span 2 / span 2 / -1 / -1;
}
.gallery img:nth-child(4) {
  grid-area: 2 / 1 / span 1 / span 2;
}
.gallery img:nth-child(5) {
  grid-area: span 1 / span 2 / -1 / -1;
}

Creo que te haces una idea de lo que está pasando aquí ahora que hemos visto algunos ejemplos usando el mismo enfoque. Definimos una grilla y colocamos imágenes en ella explícitamente, usando grid-area para que las imágenes se superpongan.

bien, pero el aspect-ratio es diferente esta vez.

¡Está! Si regresa al razonamiento que hicimos, tenemos las dos primeras imágenes que son cuadradas una al lado de la otra y tienen el mismo tamaño. Esto significa que el ancho de la cuadrícula debe ser igual al doble de su altura. Por eso, aspect-ratio: 2.

Ahora es el momento de la clip-path valores. Tenemos cuatro triángulos y un rombo.

Mostrando las tres formas únicas y los valores de clip-path que las crean.
Solo mostramos las tres formas únicas que estamos haciendo en lugar de las cinco formas en total.

Nuevamente, estoy usando Clippy para todas estas cosas matemáticas. Pero, sinceramente, puedo escribir muchas formas simples a mano, ya que pasé varios años trabajando en estrecha colaboración con clip-path, ¡y sé que tú también puedes con la práctica!

El complejo mosaico de imágenes

Aumentemos la dificultad y probemos con otro mosaico, esta vez con menos simetría y formas más complejas.

¡No te preocupes, verás que es el mismo concepto que el que acabamos de hacer! Nuevamente, imaginemos que cada imagen es un rectángulo, luego definamos la cuadrícula según lo que vemos.

Comenzaremos con dos imágenes:

Ambos son cuadrados. La primera imagen es igual a la mitad del tamaño de la segunda imagen. La primera imagen ocupa menos de la mitad del ancho de la cuadrícula, mientras que la segunda imagen ocupa más de la mitad, lo que nos da un total de Dos columnas con un tamaño diferente (el primero es igual a la mitad del segundo). La primera imagen tiene la mitad de la altura, así que asumamos automáticamente que necesitamos dos filas .

Agreguemos otra imagen al diseño.

¡Este hace las cosas un poco más complejas! Necesitamos dibujar algunas líneas para identificar cómo actualizar la configuración de la cuadrícula.

Pasaremos de una cuadrícula de 2×2 a cuatro columnas y tres filas. Bastante asimétrico, ¿verdad? Antes de intentar determinar el tamaño completo, veamos si el mismo diseño se mantiene cuando agregamos las otras imágenes.

Parece que todavía necesitamos más filas y columnas para que todo encaje en su lugar. Basándonos en las líneas de esa imagen, vamos a tener un total de cinco columnas y cuatro filas.

La lógica es simple a pesar de que el diseño es complejo, ¿verdad? Agregamos las imágenes una por una para encontrar la configuración adecuada que se adapte a todo. Ahora necesitamos identificar el tamaño de cada columna y fila.

Si decimos que la fila/columna más pequeña es igual a una fracción de la cuadrícula (1fr) obtendremos:

grid-template-columns: 1fr 1fr 2fr 3fr 5fr;

…para las columnas, y:

grid-template-rows: 3fr 1fr 2fr 2fr;

…para las filas. Podemos consolidar esto usando el grid propiedad abreviada de nuevo:

grid: 3fr 1fr 2fr 2fr / 1fr 1fr 2fr 3fr 5fr;

¡Ya sabes que hacer! Coloque las imágenes en la cuadrícula y aplique un clip-path en ellos:

.gallery img:nth-child(1) {
  grid-area: 1 / 1 /span 2 / span 3;
  clip-path: polygon(0 0, 100% 0, 0 100%);
}
.gallery img:nth-child(2) {
  grid-area: 1/2/span 3/span 3;
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
.gallery img:nth-child(3) {
  grid-area: 1 / span 2 / -1 / -1;
  clip-path: polygon(0 0, 100% 0, 100% 100%);
}
.gallery img:nth-child(4) {
  grid-area: span 3 / 1 / -1 / span 3;
  clip-path: polygon(25% 0, 100% 60%, 50% 100%, 0 100%, 0 20%);
}
.gallery img:nth-child(5) {
  grid-area: span 3/span 3/-1/-1;
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

Podemos detenernos aquí y nuestro código está bien, pero haremos un poco más para optimizar el clip-path valores. Como no tenemos espacios entre nuestras imágenes, podemos usar el hecho de que nuestras imágenes se superponen para adelgazar las cosas. Aquí hay un video para ilustrar la idea:

Como puede ver, la imagen en el medio (la que tiene la cámara) no necesita un clip-path. ¡porque las otras imágenes se superponen, dándonos la forma sin ningún trabajo adicional! Y observe que podemos usar el mismo desbordamiento de tres puntos clip-path concepto que usamos anteriormente en la imagen en la parte inferior izquierda para mantener el código más pequeño allí también.

Al final, tenemos una cuadrícula de imágenes de apariencia compleja con solo cuatro clip-path declaraciones: ¡todas ellas son polígonos de tres puntos!

Terminando

Guau, ¿verdad? No sé ustedes, pero nunca me aburro de ver lo que CSS puede hacer en estos días. No fue hace mucho tiempo que todo esto habría requerido piratería detallada y definitivamente algo de JavaScript.

A lo largo de esta serie, exploramos muchos, muchos tipos diferentes de cuadrículas de imágenes, desde las cosas básicas hasta los mosaicos complejos que hacemos hoy. Y obtuvimos mucha experiencia práctica trabajando con el recorte de CSS, ¡algo que definitivamente podrá usar en otros proyectos!

Pero antes de que terminemos con esto, tengo una tarea para ti...

Aquí hay dos mosaicos que quiero que hagas usando lo que cubrimos aquí. Uno está en el lado "más fácil" y el otro es un poco complicado. Sería realmente increíble ver tu trabajo en los comentarios, ¡así que únelos! ¡Tengo curiosidad por ver si su enfoque es diferente de cómo lo haría yo!

punto_img

Información más reciente

punto_img

Habla con nosotros!

¡Hola! ¿Le puedo ayudar en algo?