Zoom de imágenes en un diseño de cuadrícula PlatoBlockchain Data Intelligence. Búsqueda vertical. Ai.

Zoom de imágenes en un diseño de cuadrícula

Crear una cuadrícula de imágenes es fácil gracias a CSS Grid. Pero hacer que la cuadrícula haga cosas elegantes después de las imágenes que se han colocado pueden ser difíciles de lograr.

Digamos que desea agregar un efecto de desplazamiento elegante a las imágenes donde crecen y hacer zoom más allá de las filas y columnas donde se sientan. ¡Podemos hacerlo!

¿Guay, verdad? Si revisa el código, no encontrará JavaScript, selectores complejos o incluso números mágicos. ¡Y este es solo un ejemplo entre muchos que exploraremos!

Construyendo la grilla

El código HTML para crear la cuadrícula es tan simple como una lista de imágenes dentro de un contenedor. No necesitamos más que eso.

<div class="gallery">
  <img>
  <img>
  <img>
  <!-- etc. -->
</div>

Para el CSS, primero comenzamos configurando la cuadrícula usando lo siguiente:

.gallery {
  --s: 150px; /* controls the size */
  --g: 10px;  /* controls the gap */

  display: grid;
  gap: var(--g);
  width: calc(3*var(--s) + 2*var(--g)); /* 3 times the size plus 2 times the gap */
  aspect-ratio: 1;
  grid-template-columns: repeat(3, auto);
}

En resumen, tenemos dos variables, una que controla el tamaño de las imágenes y otra que establece el tamaño del espacio entre imágenes. aspect-ratio ayuda a mantener las cosas en proporción.

Quizás se pregunte por qué solo estamos definiendo tres columnas pero no filas. No, no olvidé las filas, simplemente no necesitamos configurarlas explícitamente. CSS Grid es capaz de colocar elementos automáticamente en filas y columnas implícitas, lo que significa que obtenemos tantas filas como sea necesario para cualquier número de imágenes que le arrojemos. Podemos definir explícitamente las filas en su lugar, pero necesitamos agregar grid-auto-flow: column para asegurarse de que el navegador cree las columnas necesarias para nosotros.

Aquí hay un ejemplo para ilustrar ambos casos. La diferencia es que uno fluye en un row una dirección la otra en un column dirección.

Check out este otro articulo que escribi para obtener más información sobre las cuadrículas implícitas y el algoritmo de colocación automática.

Ahora que tenemos nuestra cuadrícula, es hora de diseñar las imágenes:

.gallery > img {
  width: 0;
  height: 0;
  min-height: 100%;
  min-width: 100%;
  object-fit: cover;
}

El efecto de desplazamiento que estamos creando se basa en este CSS. Probablemente te parezca extraño que estemos creando imágenes que no tienen ni ancho ni alto, pero que tienen un ancho y un alto mínimos del 100 %. Pero verás que es un truco bastante bueno para lo que estamos tratando de lograr.

Lo que estoy haciendo aquí es decirle al navegador que las imágenes deben tener 0 ancho y alto, pero también debe tener una altura mínima igual a 100%… pero 100% ¿de que? Cuando se usan porcentajes, el valor es relativo a otra cosa. En este caso, nuestra imagen se coloca dentro de un cuadrícula de celdas y necesitamos saber ese tamaño para saber qué es 100% es relativo a.

El navegador primero ignorará min-height: 100% para calcular el tamaño de las celdas de la cuadrícula, pero utilizará el height: 0 en su calculo. Eso significa que nuestras imágenes no contribuirán al tamaño de las celdas de la cuadrícula... porque técnicamente no tienen tamaño físico. Esto dará como resultado tres columnas y filas iguales que se basan en el tamaño de la cuadrícula (que definimos en el .galleryel ancho y aspect-ratio). La altura de cada celda de la cuadrícula no es más que la variable --s definimos (lo mismo para el ancho).

Zoom de imágenes en un diseño de cuadrícula

Ahora que tenemos las dimensiones de las celdas de nuestra cuadrícula, el navegador lo usará con min-height: 100% (y min-width: 100%) que obligará a las imágenes a llenar completamente el espacio de cada celda de la cuadrícula. Todo puede parecer un poco confuso, pero la idea principal es asegurarse de que la cuadrícula defina el tamaño de las imágenes y no al revés. No quiero que la imagen defina el tamaño de la cuadrícula y comprenderá por qué después de agregar el efecto de desplazamiento.

Crear el efecto de desplazamiento

Lo que tenemos que hacer es aumentar la escala de las imágenes cuando se desplazan. Podemos hacer eso ajustando una imagen width y height on :hover:

.gallery {
  --f: 1.5; /* controls the scale factor */
}

.gallery img:hover{
  width:  calc(var(--s) * var(--f));
  height: calc(var(--s) * var(--f));
}

Agregué una nueva variable personalizada, --f, a la mezcla como un factor de escala para controlar el tamaño al pasar el mouse. Observe cómo estoy multiplicando la variable de tamaño, --s, por él para calcular el nuevo tamaño de la imagen.

Pero dijiste que el tamaño de la imagen debe ser 0. ¿Qué está pasando? Estoy perdido…

Lo que dije sigue siendo cierto, pero estoy haciendo una excepción con la imagen flotante. Le digo al navegador que solo una imagen tendrá un tamaño que no es igual a cero, por lo que contribuirá a la dimensión de la cuadrícula, mientras que todas las demás permanecerán iguales a 0.

Zoom de imágenes en un diseño de cuadrícula PlatoBlockchain Data Intelligence. Búsqueda vertical. Ai.
Zoom de imágenes en un diseño de cuadrícula

El lado izquierdo muestra la cuadrícula en su estado natural sin imágenes flotantes, que es lo que muestra el lado derecho. Todas las celdas de la cuadrícula del lado izquierdo tienen el mismo tamaño ya que todas las imágenes no tienen dimensiones físicas.

En el lado derecho, la segunda imagen de la primera fila está suspendida, lo que le da dimensiones que afectan el tamaño de la celda de la cuadrícula. El navegador hará que esa celda de cuadrícula específica sea más grande al pasar el mouse, lo que contribuye al tamaño general. Y dado que el tamaño de toda la cuadrícula está establecido (porque establecemos un valor fijo width en .gallery), las otras celdas de la cuadrícula responderán lógicamente haciéndose más pequeñas para mantener el .galleryEl tamaño total de 's intacto.

¡Ese es nuestro efecto zoom en acción! Al aumentar el tamaño de una sola imagen, afectamos a toda la configuración de la cuadrícula, y antes dijimos que la cuadrícula define el tamaño de las imágenes para que cada imagen se estire dentro de su celda de cuadrícula para llenar todo el espacio.

A esto le añadimos un toque de transition y use object-fit para evitar la distorsión de la imagen y la ilusión es perfecta!

Sé que la lógica detrás del truco no es fácil de entender. No te preocupes si no lo entiendes completamente. Lo más importante es comprender la estructura del código utilizado y cómo modificarlo para obtener más variaciones. ¡Eso es lo que haremos a continuación!

Agregando más imágenes

Creamos una cuadrícula de 3 × 3 para explicar el truco principal, pero probablemente hayas adivinado que no hay necesidad de detenerse allí. Podemos hacer variables el número de columnas y filas y añadir tantas imágenes como queramos.

.gallery {
  --n: 3; /* number of rows*/
  --m: 4; /* number of columns */
  --s: 150px; /* control the size */
  --g: 10px;  /* control the gap */
  --f: 1.5;   /* control the scale factor */

  display: grid;
  gap: var(--g);
  width:  calc(var(--m)*var(--s) + (var(--m) - 1)*var(--g));
  height: calc(var(--n)*var(--s) + (var(--n) - 1)*var(--g));
  grid-template-columns: repeat(var(--m),auto);
}

Tenemos dos nuevas variables para el número de filas y columnas. Luego, simplemente definimos el ancho y la altura de nuestra cuadrícula usándolos. Igual por grid-template-columns que utiliza el --m variable. Y al igual que antes, no necesitamos definir explícitamente las filas ya que la función de colocación automática de CSS Grid hará el trabajo por nosotros sin importar cuántos elementos de imagen estemos usando.

¿Por qué no diferentes valores para el ancho y la altura? Podemos hacerlo:

.gallery {
  --n: 3; /* number of rows*/
  --m: 4; /* number of columns */
  --h: 120px; /* control the height */
  --w: 150px; /* control the width */
  --g: 10px;  /* control the gap */
  --f: 1.5;   /* control the scale factor */

  display: grid;
  gap: var(--g);
  width:  calc(var(--m)*var(--w) + (var(--m) - 1)*var(--g));
  height: calc(var(--n)*var(--h) + (var(--n) - 1)*var(--g));
  grid-template-columns: repeat(var(--m),auto);
}

.gallery img:hover{
  width:  calc(var(--w)*var(--f));
  height: calc(var(--h)*var(--f));
}

reemplazamos --s con dos variables, una para el ancho, --w, y otro para la altura, --h. Luego ajustamos todo lo demás en consecuencia.

Entonces, comenzamos con una grilla con un tamaño y una cantidad de elementos fijos, pero luego creamos un nuevo conjunto de variables para obtener la configuración que deseamos. Todo lo que tenemos que hacer es agregar tantas imágenes como queramos y ajustar las variables CSS en consecuencia. ¡Las combinaciones son ilimitadas!

¿Qué tal una versión de pantalla completa? Sí, eso también es posible. Todo lo que necesitamos es saber qué valores debemos asignar a nuestras variables. Si queremos N filas de imágenes y queremos que nuestra cuadrícula sea de pantalla completa, primero debemos resolver una altura de 100vh:

var(--n) * var(--h) + (var(--n) - 1) * var(--g) = 100vh

La misma lógica para el ancho, pero usando vw en lugar de vh:

var(--m) * var(--w) + (var(--m) - 1) * var(--g) = 100vw

Hacemos los cálculos para obtener:

--w: (100vw - (var(--m) - 1) * var(--g)) / var(--m)
--h: (100vh - (var(--n) - 1) * var(--g)) / var(--n)

¡Hecho!

Es exactamente el mismo HTML pero con algunas variables actualizadas que cambian el tamaño y el comportamiento de la cuadrícula.

Tenga en cuenta que he omitido la fórmula que establecimos previamente en el .galleryes width y height y los reemplazó con 100vw y 100vh, respectivamente. La fórmula nos dará el mismo resultado, pero como sabemos qué valor queremos, podemos deshacernos de toda esa complejidad añadida.

También podemos simplificar el --h y --w eliminando la brecha de la ecuación a favor de esto:

--h: calc(100vh / var(--n)); /* Viewport height divided by number of rows */
--w: calc(100vw / var(--m)); /* Viewport width divided by number of columns */

Esto hará que la imagen flotante crezca un poco más que en el ejemplo anterior, pero no es gran cosa ya que podemos controlar la escala con el --f variable que estamos usando como multiplicador.

Y dado que las variables se usan en un solo lugar, aún podemos simplificar el código eliminándolas por completo:

Es importante tener en cuenta que esta optimización se aplica solo al ejemplo de pantalla completa y no a los ejemplos que hemos cubierto. Este ejemplo es un caso particular en el que podemos hacer que el código sea más liviano eliminando parte del trabajo de cálculo complejo que necesitábamos en los otros ejemplos.

De hecho, tenemos todo lo que necesitamos para crear el popular patrón de paneles expandibles:

Profundicemos aún más

¿Notaste que nuestro factor de escala puede ser menor que 1? Podemos definir el tamaño de la imagen flotante para que sea más pequeño que --h or --w pero la imagen se hace más grande al pasar el mouse.

El tamaño inicial de la celda de la cuadrícula es igual a --w y --h, entonces, ¿por qué los valores más pequeños hacen que la celda de la cuadrícula más grande? ¿No debería la celda obtener menores, o al menos mantener su tamaño inicial? ¿Y cuál es el tamaño final de la celda de la cuadrícula?

Necesitamos profundizar en cómo el algoritmo CSS Grid calcula el tamaño de las celdas de la cuadrícula. Y esto implica comprender el valor predeterminado de CSS Grid estiramiento de alineación.

Aquí hay un ejemplo para entender la lógica.

En el lado izquierdo de la demostración, definí dos columnas con auto ancho. Obtenemos el resultado intuitivo: dos columnas iguales (y dos celdas de cuadrícula iguales). Pero la cuadrícula que configuré en el lado derecho de la demostración, donde estoy actualizando la alineación usando place-content: start, parece no tener nada.

DevTools nos ayuda a mostrarnos lo que realmente sucede en ambos casos:

Zoom de imágenes en un diseño de cuadrícula PlatoBlockchain Data Intelligence. Búsqueda vertical. Ai.
Zoom de imágenes en un diseño de cuadrícula

En la segunda cuadrícula, tenemos dos columnas, pero sus anchos son iguales a cero, por lo que obtenemos dos celdas de cuadrícula que están colapsadas en la esquina superior izquierda del contenedor de la cuadrícula. Esto es no un error sino el resultado lógico de la alineación de la cuadrícula. Cuando dimensionamos una columna (o fila) con auto, significa que su contenido dicta su tamaño, pero tenemos un vacío div sin contenido para dejar espacio.

Pero desde stretch es la alineación predeterminada y tenemos suficiente espacio dentro de nuestra cuadrícula, el navegador estirará ambas celdas de la cuadrícula por igual para cubrir toda esa área. Así es como la cuadrícula de la izquierda termina con dos columnas iguales.

Desde la especificación:

Tenga en cuenta que ciertos valores de justify-content y align-content puede hacer que las pistas se separen (space-around, space-between, space-evenly) o para ser redimensionado (stretch).

Tenga en cuenta el "redimensionado", que es la clave aquí. En el último ejemplo, usé place-content cual es la abreviatura de justify-content y align-content

Y esto está enterrado en algún lugar de el algoritmo de tamaño de cuadrícula especificaciones:

Este paso expande las pistas que tienen un auto función de tamaño máximo de pista dividiendo cualquier resto positivo, definido espacio libre por igual entre ellos. Si el espacio libre es indefinido, Pero el contenedor de rejilla tiene un definido min-ancho / alto, use ese tamaño para calcular el espacio libre para este paso.

“Equally” explica por qué terminamos con celdas de cuadrícula iguales, pero se aplica al “espacio libre”, que es muy importante.

Tomemos el ejemplo anterior y agreguemos contenido a uno de los divs:

Agregamos un cuadrado 50px imagen. Aquí hay una ilustración de cómo cada cuadrícula en nuestro ejemplo responde a esa imagen:

Zoom de imágenes en un diseño de cuadrícula PlatoBlockchain Data Intelligence. Búsqueda vertical. Ai.
Zoom de imágenes en un diseño de cuadrícula

En el primer caso, podemos ver que la primera celda (en rojo) es más grande que la segunda (en azul). En el segundo caso, el tamaño de la primera celda cambia para adaptarse al tamaño físico de la imagen, mientras que la segunda celda permanece sin dimensiones. El espacio libre se divide por igual, pero la primera celda tiene más contenido dentro, lo que la hace más grande.

Esta es la matemática para averiguar nuestro espacio libre:

(grid width) - (gap) - (image width) = (free space)
200px - 5px - 50px = 145px 

Dividido por dos, el número de columnas, obtenemos un ancho de 72.5px para cada columna. Pero añadimos el tamaño de la imagen, 50px, a la primera columna que nos deja con una columna en 122.5px y el segundo igual a 72.5px.

La misma lógica se aplica a nuestra cuadrícula de imágenes. Todas las imágenes tienen un tamaño igual a 0 (sin contenido) mientras que la imagen sobre el cursor contribuye al tamaño, incluso si es solo 1px - haciendo que su celda de cuadrícula sea más grande que las demás. Por esta razón, el factor de escala puede ser cualquier valor mayor que 0 incluso decimales entre 0 y 1.

Para obtener el ancho final de las celdas de la cuadrícula, hacemos el mismo cálculo para obtener lo siguiente:

(container width) - (sum of all gaps) - (hovered image width) = (free space)

El ancho del contenedor está definido por:

var(--m)*var(--w) + (var(--m) - 1)*var(--g)

…y todos los huecos son iguales a:

(var(--m) - 1)*var(--g)

… y para la imagen flotante tenemos:

var(--w)*var(--f)

Podemos calcular todo eso con nuestras variables:

var(--m)*var(--w) - var(--w)*var(--f) = var(--w)*(var(--m) - var(--f))

El número de columnas está definido por --m , por lo que dividimos ese espacio libre en partes iguales para obtener:

var(--w)*(var(--m) - var(--f))/var(--m)

…lo que nos da el tamaño de las imágenes no flotantes. Para imágenes flotantes, tenemos esto:

var(--w)*(var(--m) - var(--f))/var(--m) + var(--w)*var(--f)
var(--w)*((var(--m) - var(--f))/var(--m) + var(--f))

Si queremos controlar el tamaño final de la imagen flotante, consideramos la fórmula anterior para obtener el tamaño exacto que queremos. Si por ejemplo queremos que la imagen sea el doble de grande:

(var(--m) - var(--f))/var(--m) + var(--f) = 2

Entonces, el valor de nuestro multiplicador de escala, --f, debe ser igual a:

var(--m)/(var(--m) - 1)

Para tres columnas tendremos 3/2 = 1.5 ¡y ese es el factor de escala que usé en la primera demostración de este artículo porque quería que la imagen fuera el doble de grande al pasar el mouse por encima!

La misma lógica se aplica al cálculo de la altura y, en caso de que queramos controlarlos a ambos de forma independiente, tendremos que considerar dos factores de escala para asegurarnos de que tenemos un ancho y una altura específicos al pasar el mouse.

.gallery {
  /* same as before */
   --fw: 1.5; /* controls the scale factor for the width */
   --fh: 1.2; /* controls the scale factor for the height */

  /* same as before */
}

.gallery img:hover{
  width:  calc(var(--w)*var(--fw));
  height: calc(var(--h)*var(--fh));
}

Ahora, conoce todos los secretos para crear cualquier tipo de cuadrícula de imagen con un efecto de desplazamiento genial y, al mismo tiempo, tiene el control del tamaño que desea utilizando las matemáticas que acabamos de cubrir.

Terminando

En mi último artículo, creamos una cuadrícula de aspecto complejo con unas pocas líneas de CSS que ponen en uso las funciones implícitas de cuadrícula y ubicación automática de CSS Grid. En este artículo, nos basamos en algunos trucos de tamaño de cuadrícula CSS para crear una cuadrícula elegante de imágenes que se acercan al pasar el mouse y hacen que la cuadrícula se ajuste en consecuencia. ¡Todo esto con un código simplificado que es fácil de ajustar usando variables CSS!

¡En el próximo artículo, jugaremos con las formas! Combinaremos la cuadrícula CSS con la máscara y la ruta de recorte para obtener una cuadrícula de imágenes elegante.

Sello de tiempo:

Mas de Trucos CSS