Zoom delle immagini in un layout a griglia PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Zoom di immagini in un layout a griglia

Creare una griglia di immagini è facile, grazie a CSS Grid. Ma fare in modo che la griglia faccia cose stravaganti dopo le immagini sono state posizionate può essere difficile da estrarre.

Dici di voler aggiungere un effetto al passaggio del mouse fantasioso alle immagini in cui crescono e ingrandiscono oltre le righe e le colonne in cui si trovano? Possiamo farlo!

Bello, vero? Se controlli il codice, non troverai JavaScript, selettori complessi o addirittura numeri magici. E questo è solo un esempio tra i tanti che esploreremo!

Costruire la griglia

Il codice HTML per creare la griglia è semplice come un elenco di immagini all'interno di un contenitore. Non abbiamo bisogno di più di questo.

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

Per il CSS, iniziamo prima impostando la griglia usando quanto segue:

.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);
}

In breve, abbiamo due variabili, una che controlla la dimensione delle immagini e l'altra che imposta la dimensione del divario tra le immagini. aspect-ratio aiuta a mantenere le cose in proporzione.

Ti starai chiedendo perché stiamo definendo solo tre colonne ma nessuna riga. No, non ho dimenticato le righe: semplicemente non è necessario impostarle in modo esplicito. CSS Grid è in grado di posizionare automaticamente gli elementi righe e colonne implicite, il che significa che otteniamo tutte le righe necessarie per qualsiasi numero di immagini che gli lanciamo. Possiamo invece definire esplicitamente le righe ma dobbiamo aggiungere grid-auto-flow: column per assicurarci che il browser crei per noi le colonne necessarie.

Ecco un esempio per illustrare entrambi i casi. La differenza è che si scorre in a row direzione un l'altro in a column direzione.

Check out questo altro articolo che ho scritto per ulteriori informazioni sulle griglie implicite e sull'algoritmo di posizionamento automatico.

Ora che abbiamo la nostra griglia, è il momento di modellare le immagini:

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

L'effetto hover che stiamo creando si basa su questo CSS. Probabilmente ti sembra strano che stiamo realizzando immagini che non hanno né larghezza né altezza ma hanno una larghezza e un'altezza minime del 100%. Ma vedrai che è un trucco piuttosto accurato per quello che stiamo cercando di ottenere.

Quello che sto facendo qui è dire al browser che le immagini devono avere 0 larghezza e altezza ma devono anche avere un'altezza minima pari a 100%… ma 100% di cosa? Quando si utilizzano le percentuali, il valore è rispetto a qualcos'altro. In questo caso, la nostra immagine è collocata all'interno di a cella della griglia e abbiamo bisogno di conoscere quella dimensione per sapere cosa c'è 100% è relativo a.

Il browser prima ignorerà min-height: 100% per calcolare la dimensione delle celle della griglia, ma utilizzerà il height: 0 nel suo calcolo. Ciò significa che le nostre immagini non contribuiranno alla dimensione delle celle della griglia... perché tecnicamente non hanno dimensioni fisiche. Ciò si tradurrà in tre colonne e righe uguali basate sulla dimensione della griglia (che abbiamo definito in .gallery's larghezza e aspect-ratio). L'altezza di ciascuna cella della griglia non è altro che la variabile --s abbiamo definito (lo stesso per la larghezza).

Zoom di immagini in un layout a griglia

Ora che abbiamo le dimensioni delle celle della nostra griglia, il browser la utilizzerà con min-height: 100% (E min-width: 100%) che forzerà le immagini a riempire completamente lo spazio di ciascuna cella della griglia. Il tutto può sembrare un po' confuso, ma l'idea principale è assicurarsi che la griglia definisca la dimensione delle immagini piuttosto che il contrario. Non voglio che l'immagine definisca la dimensione della griglia e capirai perché dopo aver aggiunto l'effetto hover.

Creazione dell'effetto al passaggio del mouse

Quello che dobbiamo fare è aumentare la scala delle immagini quando sono in bilico. Possiamo farlo regolando un'immagine width ed 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));
}

Ho aggiunto una nuova variabile personalizzata, --f, al mix come fattore di scala per controllare la dimensione al passaggio del mouse. Nota come sto moltiplicando la variabile size, --s, da esso per calcolare la nuova dimensione dell'immagine.

Ma hai detto che la dimensione dell'immagine deve essere 0. Cosa sta succedendo? Mi sono perso…

Quello che ho detto è ancora vero, ma sto facendo un'eccezione per l'immagine sospesa. Sto dicendo al browser che solo un'immagine avrà una dimensione che non è uguale a zero - quindi contribuirà alla dimensione della griglia - mentre tutte le altre rimarranno uguali a 0.

Zoom delle immagini in un layout a griglia PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
Zoom di immagini in un layout a griglia

Il lato sinistro mostra la griglia nel suo stato naturale senza immagini in bilico, che è ciò che mostra il lato destro. Tutte le celle della griglia sul lato sinistro hanno dimensioni uguali poiché tutte le immagini non hanno dimensioni fisiche.

Sul lato destro, è posizionata la seconda immagine nella prima riga, il che le conferisce dimensioni che influiscono sulle dimensioni della cella della griglia. Il browser ingrandirà quella specifica cella della griglia al passaggio del mouse, il che contribuisce alle dimensioni complessive. E poiché la dimensione dell'intera griglia è impostata (perché impostiamo un valore fisso width sul .gallery), le altre celle della griglia risponderanno logicamente diventando più piccole per mantenere il .galleryLa dimensione complessiva è intatta.

Questo è il nostro effetto zoom in azione! Aumentando la dimensione di una sola immagine influenziamo l'intera configurazione della griglia, e abbiamo detto prima che la griglia definisce la dimensione delle immagini in modo che ogni immagine si allunghi all'interno della sua cella della griglia per riempire tutto lo spazio.

A questo, aggiungiamo un tocco di transition E l'uso object-fit per evitare la distorsione dell'immagine e l'illusione è perfetta!

So che la logica dietro il trucco non è facile da capire. Non preoccuparti se non lo capisci completamente. La cosa più importante è capire la struttura del codice utilizzato e come modificarlo per ottenere più variazioni. Questo è ciò che faremo dopo!

Aggiunta di più immagini

Abbiamo creato una griglia 3×3 per spiegare il trucco principale, ma probabilmente hai intuito che non avremmo dovuto fermarci qui. Possiamo rendere variabile il numero di colonne e righe e aggiungere tutte le immagini che vogliamo.

.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);
}

Abbiamo due nuove variabili per il numero di righe e colonne. Quindi definiamo semplicemente la larghezza e l'altezza della nostra griglia usandole. Lo stesso per grid-template-columns che usa il --m variabile. E proprio come prima, non abbiamo bisogno di definire esplicitamente le righe poiché la funzione di posizionamento automatico della griglia CSS farà il lavoro per noi, indipendentemente dal numero di elementi dell'immagine che stiamo usando.

Perché non valori diversi per la larghezza e l'altezza? Possiamo farlo:

.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));
}

Sostituiamo --s con due variabili, una per la larghezza, --w, e un altro per l'altezza, --h. Quindi aggiustiamo tutto il resto di conseguenza.

Quindi, abbiamo iniziato con una griglia con una dimensione fissa e un numero di elementi, ma poi abbiamo creato un nuovo insieme di variabili per ottenere qualsiasi configurazione desideriamo. Tutto quello che dobbiamo fare è aggiungere tutte le immagini che vogliamo e regolare di conseguenza le variabili CSS. Le combinazioni sono infinite!

Che ne dici di una versione a schermo intero? Sì, è anche possibile. Tutto ciò di cui abbiamo bisogno è sapere quali valori dobbiamo assegnare alle nostre variabili. Se vogliamo N righe di immagini e vogliamo che la nostra griglia sia a schermo intero, dobbiamo prima risolvere per un'altezza di 100vh:

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

Stessa logica per la larghezza, ma in uso vw invece di vh:

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

Facciamo i calcoli per ottenere:

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

Fatto!

È lo stesso HTML esatto ma con alcune variabili aggiornate che cambiano le dimensioni e il comportamento della griglia.

Si noti che ho omesso la formula precedentemente impostata su .gallery'S width ed height e li ha sostituiti con 100vw ed 100vh, rispettivamente. La formula ci darà lo stesso risultato, ma poiché sappiamo quale valore vogliamo, possiamo abbandonare tutta quella complessità aggiunta.

Possiamo anche semplificare il --h ed --w rimuovendo il divario dall'equazione a favore di questo:

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

Ciò farà crescere l'immagine al passaggio del mouse un po' di più rispetto all'esempio precedente, ma non è un grosso problema poiché possiamo controllare la scala con il --f variabile che stiamo usando come moltiplicatore.

E poiché le variabili vengono utilizzate in un unico posto, possiamo comunque semplificare il codice rimuovendole del tutto:

È importante notare che questa ottimizzazione si applica solo all'esempio a schermo intero e non agli esempi che abbiamo trattato. Questo esempio è un caso particolare in cui possiamo alleggerire il codice rimuovendo parte del complesso lavoro di calcolo di cui avevamo bisogno negli altri esempi.

In realtà abbiamo tutto ciò di cui abbiamo bisogno per creare il popolare modello di pannelli espandibili:

Scaviamo ancora più a fondo

Hai notato che il nostro fattore di scala può essere inferiore a 1? Possiamo definire la dimensione dell'immagine al passaggio del mouse più piccola di --h or --w ma l'immagine diventa più grande al passaggio del mouse.

La dimensione iniziale della cella della griglia è uguale a --w ed --h, quindi perché un valore più piccolo crea la cella della griglia maggiore? La cellula non dovrebbe arrivare inferiore , o almeno mantenere la sua dimensione iniziale? E qual è la dimensione finale della cella della griglia?

Dobbiamo approfondire il modo in cui l'algoritmo CSS Grid calcola la dimensione delle celle della griglia. E questo implica la comprensione dell'impostazione predefinita di CSS Grid allungare l'allineamento.

Ecco un esempio per capire la logica.

Sul lato sinistro della demo, ho definito una due colonne con auto larghezza. Otteniamo il risultato intuitivo: due colonne uguali (e due celle della griglia uguali). Ma la griglia che ho impostato sul lato destro della demo, dove sto aggiornando l'allineamento usando place-content: start, sembra non avere nulla.

DevTools ci aiuta a mostrarci cosa sta realmente accadendo in entrambi i casi:

Zoom delle immagini in un layout a griglia PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
Zoom di immagini in un layout a griglia

Nella seconda griglia, abbiamo due colonne, ma la loro larghezza è uguale a zero, quindi otteniamo due celle della griglia che sono compresse nell'angolo in alto a sinistra del contenitore della griglia. Questo è non un bug ma il risultato logico dell'allineamento della griglia. Quando ridimensioniamo una colonna (o riga) con auto, significa che il suo contenuto determina la sua dimensione, ma abbiamo un vuoto div senza contenuti a cui fare spazio.

Ma da allora stretch è l'allineamento predefinito e abbiamo abbastanza spazio all'interno della nostra griglia, il browser allungherà entrambe le celle della griglia allo stesso modo per coprire tutta quell'area. È così che la griglia a sinistra finisce con due colonne uguali.

Da la specifica:

Si noti che alcuni valori di justify-content ed align-content può causare la spaziatura delle tracce (space-around, space-between, space-evenly) o da ridimensionare (stretch).

Nota il "da ridimensionare" che è la chiave qui. Nell'ultimo esempio, ho usato place-content che è la scorciatoia per justify-content ed align-content

E questo è sepolto da qualche parte dentro l'algoritmo di dimensionamento della griglia Specifiche:

Questo passaggio espande le tracce che hanno un auto funzione di dimensionamento massimo della traccia dividendo l'eventuale positivo residuo, definito spazio libero ugualmente tra loro. Se lo spazio libero è indefinito, Ma l' contenitore a griglia ha un definito larghezza/altezza min, usa invece quella dimensione per calcolare lo spazio libero per questo passaggio.

"Ugualmente" spiega perché finiamo con le celle della griglia uguali, ma si applica allo "spazio libero" che è molto importante.

Prendiamo l'esempio precedente e aggiungiamo contenuto a uno dei file divs:

Abbiamo aggiunto un quadrato 50px Immagine. Ecco un'illustrazione di come ciascuna griglia nel nostro esempio risponde a quell'immagine:

Zoom delle immagini in un layout a griglia PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
Zoom di immagini in un layout a griglia

Nel primo caso, possiamo vedere che la prima cella (in rosso) è più grande della seconda (in blu). Nel secondo caso, la dimensione della prima cella cambia per adattarsi alla dimensione fisica dell'immagine mentre la seconda cella rimane senza dimensioni. Lo spazio libero è diviso equamente, ma la prima cella ha più contenuto all'interno che la rende più grande.

Questa è la matematica per capire il nostro spazio libero:

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

Diviso per due — il numero di colonne — otteniamo una larghezza di 72.5px per ogni colonna. Ma aggiungiamo la dimensione dell'immagine, 50px, alla prima colonna che ci lascia con una colonna a 122.5px e il secondo uguale a 72.5px.

La stessa logica si applica alla nostra griglia di immagini. Tutte le immagini hanno una dimensione uguale a 0 (nessun contenuto) mentre l'immagine al passaggio del mouse contribuisce alle dimensioni, anche se è solo 1px — rendendo la sua cella della griglia più grande delle altre. Per questo motivo, il fattore di scala può essere qualsiasi valore maggiore di 0 anche decimali tra 0 ed 1.

Per ottenere la larghezza finale delle celle della griglia, eseguiamo lo stesso calcolo per ottenere quanto segue:

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

La larghezza del contenitore è definita da:

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

…e tutti gli intervalli sono uguali a:

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

…e per l'immagine sospesa abbiamo:

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

Possiamo calcolare tutto questo con le nostre variabili:

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

Il numero di colonne è definito da --m , quindi dividiamo lo spazio libero equamente per ottenere:

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

...che ci dà la dimensione delle immagini non sospese. Per le immagini al passaggio del mouse, abbiamo questo:

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

Se vogliamo controllare la dimensione finale dell'immagine al passaggio del mouse, consideriamo la formula sopra per ottenere la dimensione esatta che desideriamo. Se, ad esempio, vogliamo che l'immagine sia grande il doppio:

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

Quindi, il valore del nostro moltiplicatore di scala, --f, deve essere uguale a:

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

Per tre colonne avremo 3/2 = 1.5 e questo è il fattore di scala che ho usato nella prima demo di questo articolo perché volevo rendere l'immagine due volte più grande al passaggio del mouse!

La stessa logica si applica al calcolo dell'altezza e nel caso in cui desideriamo controllarli entrambi indipendentemente, dovremo considerare due fattori di scala per assicurarci di avere una larghezza e un'altezza specifiche al passaggio del 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));
}

Ora conosci tutti i segreti per creare qualsiasi tipo di griglia di immagini con un fantastico effetto al passaggio del mouse, controllando anche le dimensioni desiderate usando la matematica che abbiamo appena spiegato.

Concludendo

Nel mio ultimo articolo, abbiamo creato una griglia dall'aspetto complesso con poche righe di CSS che utilizza la griglia implicita di CSS Grid e le funzioni di posizionamento automatico. In questo articolo, ci siamo basati su alcuni trucchi di dimensionamento della griglia CSS per creare una griglia di immagini fantasiosa che ingrandisce il passaggio del mouse e fa sì che la griglia si regoli di conseguenza. Tutto questo con un codice semplificato e facile da regolare utilizzando le variabili CSS!

Nel prossimo articolo giocheremo con le forme! Combineremo la griglia CSS con la maschera e il percorso di clip per ottenere una griglia di immagini fantasiosa.

Timestamp:

Di più da Trucchi CSS