Griglia CSS e forme personalizzate, parte 1 PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Griglia CSS e forme personalizzate, parte 1

In un articolo precedente, ho esaminato la capacità di CSS Grid di crea layout complessi usando i suoi poteri di posizionamento automatico. Ho fatto un ulteriore passo avanti in un altro articolo che aggiunto un effetto di zoom al passaggio del mouse alle immagini in un layout a griglia. Questa volta, voglio immergermi in un altro tipo di griglia, che funzioni con le forme.

Ad esempio, cosa succede se le immagini non sono perfettamente quadrate ma invece hanno la forma di esagoni o rombi? Avviso spoiler: ce la possiamo fare. In effetti, combineremo le tecniche CSS Grid che abbiamo esaminato e inseriremo alcuni CSS clip-path ed mask magia per creare fantasiose griglie di immagini per qualsiasi forma tu possa immaginare!

Iniziamo con un po' di markup

La maggior parte dei layout che esamineremo può sembrare facile da realizzare a prima vista, ma la parte difficile è realizzarli con lo stesso codice HTML. Possiamo usare molti involucri, divs, e quant'altro, ma l'obiettivo di questo post è utilizzare la stessa e minima quantità di codice HTML e ottenere comunque tutte le diverse griglie che desideriamo. Dopotutto, cos'è il CSS se non un modo per separare lo stile e il markup? Il nostro stile non dovrebbe dipendere dal markup e viceversa.

Detto questo, iniziamo con questo:

<div class="gallery">
  <img src="..." alt="...">
  <img src="..." alt="...">
  <img src="..." alt="...">
  <img src="..." alt="...">
  <!-- as many times as we want -->
</div>

Un contenitore con le immagini è tutto ciò di cui abbiamo bisogno qui. Niente di più!

Griglia CSS di esagoni

Questo è anche a volte indicato come una griglia "a nido d'ape".

Ci sono già molti altri post sul blog là fuori che mostrano come farlo. Cavolo, io ne ha scritto uno qui su CSS-Tricks! Quell'articolo è ancora buono e approfondisce la creazione di un layout reattivo. Ma per questo caso specifico, faremo affidamento su un approccio CSS molto più semplice.

Per prima cosa, usiamo clip-path sulle immagini per creare la forma esagonale e le posizioniamo tutte nella stessa area della griglia in modo che si sovrappongano.

.gallery {
  --s: 150px; /* controls the size */
  display: grid;
}

.gallery > img {
  grid-area: 1/1;
  width: var(--s);
  aspect-ratio: 1.15;
  object-fit: cover;
  clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0 50%);
}
clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0 50%)

Niente di speciale ancora. Tutte le immagini sono esagoni e una sopra l'altra. Quindi sembra che tutto ciò che abbiamo sia un singolo elemento dell'immagine a forma esagonale, ma in realtà ce ne sono sette.

Il passaggio successivo consiste nell'applicare una traduzione alle immagini per posizionarle correttamente sulla griglia.

Griglia CSS e forme personalizzate, parte 1 PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
Griglia CSS e forme personalizzate, parte 1

Si noti che vogliamo ancora che una delle immagini rimanga al centro. Il resto viene posizionato attorno ad esso usando CSS translate e la buona vecchia geometria. Ecco le formule fittizie che ho escogitato per ogni immagine nella griglia:

translate((height + gap)*sin(0deg), (height + gap)*cos(0))
translate((height + gap)*sin(60deg), (height + gap)*cos(60deg))
translate((height + gap)*sin(120deg), (height + gap)*cos(120deg))
translate((height + gap)*sin(180deg), (height + gap)*cos(180deg))
translate((height + gap)*sin(240deg), (height + gap)*cos(240deg))
translate((height + gap)*sin(300deg), (height + gap)*cos(300deg))

Alcuni calcoli e ottimizzazione dopo (saltando quella parte noiosa, giusto?) otteniamo il seguente CSS:

.gallery {
  --s: 150px; /* control the size */
  --g: 10px;  /* control the gap */
  display: grid;
}
.gallery > img {
  grid-area: 1/1;
  width: var(--s);
  aspect-ratio: 1.15;
  object-fit: cover;
  clip-path: polygon(25% 0%, 75% 0%, 100% 50% ,75% 100%, 25% 100%, 0 50%);
  transform: translate(var(--_x,0), var(--_y,0));
}
.gallery > img:nth-child(1) { --_y: calc(-100% - var(--g)); }
.gallery > img:nth-child(7) { --_y: calc( 100% + var(--g)); }
.gallery > img:nth-child(3),
.gallery > img:nth-child(5) { --_x: calc(-75% - .87*var(--g)); }
.gallery > img:nth-child(4),
.gallery > img:nth-child(6) { --_x: calc( 75% + .87*var(--g)); }
.gallery > img:nth-child(3),
.gallery > img:nth-child(4) { --_y: calc(-50% - .5*var(--g)); }
.gallery > img:nth-child(5), 
.gallery > img:nth-child(6) { --_y: calc( 50% + .5*var(--g)); }

Forse sarà più facile quando arriveremo funzioni trigonometriche reali nei CSS!

Ogni immagine è tradotta dal --_x ed --_y variabili basate su tali formule. Solo la seconda immagine (nth-child(2)) non è definito in nessun selettore perché è quello al centro. Può essere qualsiasi immagine se decidi di utilizzare un ordine diverso. Ecco l'ordine che sto usando:

Griglia CSS e forme personalizzate, parte 1 PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
Griglia CSS e forme personalizzate, parte 1

Con solo poche righe di codice, otteniamo una bella griglia di immagini. A questo, ho aggiunto un piccolo effetto hover alle immagini per rendere le cose più fantasiose.

Indovina un po? Possiamo ottenere un'altra griglia esagonale semplicemente aggiornando alcuni valori.

Se controlli il codice e lo confronti con il precedente noterai che ho semplicemente scambiato i valori all'interno clip-path e ho cambiato --x ed --y. È tutto!

Griglia CSS di rombi

Rombo è una parola così elegante per un quadrato ruotato di 45 gradi.

Stesso HTML, ricordi? Per prima cosa iniziamo definendo una griglia 2×2 di immagini in CSS:

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

  display: grid;
  gap: 10px;
  grid: auto-flow var(--s) / repeat(2, var(--s));
  place-items: center;
}
.gallery > img {
  width: 100%; 
  aspect-ratio: 1;
  object-fit: cover;
}

La prima cosa che potrebbe attirare la tua attenzione è il grid proprietà. È usato in modo piuttosto raro ma è molto utile in quanto è una scorciatoia che ti consente di definire una griglia completa in una dichiarazione. Non è la proprietà più intuitiva, e per non dire leggibile, ma siamo qui per farlo imparare ed scopri nuove cose, quindi usiamolo invece di scrivere tutte le singole proprietà della griglia.

grid: auto-flow var(--s) / repeat(2,var(--s));

/* is equivalent to this: */
grid-template-columns: repeat(2, var(--s));
grid-auto-rows: var(--s);

Questo definisce due colonne uguali a --s variabile e imposta l'altezza di tutte le righe su --s anche. Dato che abbiamo quattro immagini, otterremo automaticamente una griglia 2×2.

Ecco un altro modo in cui avremmo potuto scriverlo:

grid-template-columns: repeat(2, var(--s));
grid-template-rows: repeat(2, var(--s));

...che può essere ridotto con il grid abbreviazione:

grid: repeat(2,var(--s)) / repeat(2,var(--s));

Dopo aver impostato la griglia, la ruotiamo e le immagini con CSS transformse otteniamo questo:

Nota come li ruoto entrambi di 45deg, ma nella direzione opposta.

.gallery {
  /* etc. */
  transform: rotate(45deg);
}
.gallery > img {
  /* etc. */
  transform: rotate(-45deg);
}

La rotazione delle immagini in direzione negativa impedisce che vengano ruotate con la griglia in modo che rimangano dritte. Ora applichiamo a clip-path per ritagliare una forma a rombo da loro.

Griglia CSS e forme personalizzate, parte 1 PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%)

Abbiamo quasi finito! Dobbiamo correggere le dimensioni dell'immagine per farle combaciare. Altrimenti, sono distanziati tra loro fino al punto in cui non sembra una griglia di immagini.

Griglia CSS e forme personalizzate, parte 1 PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
Griglia CSS e forme personalizzate, parte 1

L'immagine si trova all'interno del confine del cerchio verde, che è il cerchio inscritto dell'area della griglia in cui è posizionata l'immagine. Quello che vogliamo è rendere l'immagine più grande per adattarsi al cerchio rosso, che è il cerchio circoscritto dell'area della griglia.

Non preoccuparti, non introdurrò più geometrie noiose. Tutto quello che devi sapere è che la relazione tra il raggio di ogni cerchio è la radice quadrata di 2 (sqrt(2)). Questo è il valore di cui abbiamo bisogno per aumentare la dimensione delle nostre immagini per riempire l'area. Noi useremo 100%*sqrt(2) = 141% e basta!

.gallery {
  --s: 150px; /* control the size */

  display: grid;
  grid: auto-flow var(--s) / repeat(2,var(--s));
  gap: 10px;
  place-items: center;
  transform: rotate(45deg);
}
.gallery > img {
  width: 141%; /* 100%*sqrt(2) = 141% */
  aspect-ratio: 1;
  object-fit: cover;
  transform: rotate(-45deg);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}

Come la griglia esagonale, possiamo rendere le cose più fantasiose con quel bel effetto di zoomata al passaggio del mouse:

Griglia CSS di forme triangolari

Probabilmente ormai sai che il grande trucco è capire il clip-path per ottenere le forme che vogliamo. Per questa griglia, ogni elemento ha il suo clip-path value mentre le ultime due griglie hanno lavorato con una forma coerente. Quindi, questa volta, è come se stessimo lavorando con alcune forme triangolari diverse che si uniscono per formare una griglia rettangolare di immagini.

Griglia CSS e forme personalizzate, parte 1 PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
Le tre immagini in alto
Griglia CSS e forme personalizzate, parte 1 PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
Le tre immagini in basso

Li posizioniamo all'interno di una griglia 3×2 con il seguente CSS:

.gallery {
  display: grid;
  gap: 10px; 
  grid-template-columns: auto auto auto; /* 3 columns */
  place-items: center;
}
.gallery > img {
  width: 200px; /* controls the size */
  aspect-ratio: 1;
  object-fit: cover;
}
/* the clip-path values */
.gallery > img:nth-child(1) { clip-path: polygon(0 0, 50% 0, 100% 100% ,0 100%); }
.gallery > img:nth-child(2) { clip-path: polygon(0 0, 100% 0, 50% 100%); }
.gallery > img:nth-child(3) { clip-path: polygon(50% 0, 100% 0, 100% 100%, 0 100%); }
.gallery > img:nth-child(4) { clip-path: polygon(0 0, 100% 0, 50% 100%, 0 100%); }
.gallery > img:nth-child(5) { clip-path: polygon(50% 0, 100% 100%, 0% 100%); }
.gallery > img:nth-child(6) { clip-path: polygon(0 0, 100% 0 ,100% 100%, 50% 100%); } }

Ecco cosa otteniamo:

Il tocco finale è rendere uguale la larghezza della colonna centrale 0 per eliminare gli spazi tra le immagini. Lo stesso tipo di problema di spaziatura che abbiamo avuto con la griglia a rombi, ma con un approccio diverso per le forme che stiamo usando:

grid-template-columns: auto 0 auto;

Ho dovuto giocherellare con il clip-path valori per assicurarsi che sembrino combaciare perfettamente come un puzzle. Le immagini originali si sovrappongono quando la colonna centrale ha larghezza zero, ma dopo aver tagliato le immagini, l'illusione è perfetta:

Griglia CSS e forme personalizzate, parte 1 PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
Griglia CSS e forme personalizzate, parte 1

Griglia per pizza CSS

Indovina un po? Possiamo ottenere un'altra griglia interessante semplicemente aggiungendo border-radius ed overflow alla nostra griglia o forme triangolari. 🎉

Griglia CSS di pezzi di puzzle

Questa volta giocheremo con i CSS mask proprietà per far sembrare le immagini come pezzi di un puzzle.

Se non l'hai usato mask con gradienti CSS, Consiglio vivamente questo altro articolo Ho scritto sull'argomento perché aiuterà con ciò che verrà dopo. Perché i gradienti? Perché è quello che stiamo usando per ottenere le tacche rotonde nelle forme dei pezzi del puzzle.

L'impostazione della griglia dovrebbe essere un gioco da ragazzi ormai, quindi concentriamoci invece sul mask parte.

Come illustrato nella demo sopra, abbiamo bisogno di due gradienti per creare la forma finale. Un gradiente crea un cerchio (la parte verde) e l'altro crea la curva giusta mentre riempie la parte superiore.

--g: 6px; /* controls the gap */
--r: 42px;  /* control the circular shapes */

background: 
  radial-gradient(var(--r) at left 50% bottom var(--r), green 95%, #0000),
  radial-gradient(calc(var(--r) + var(--g)) at calc(100% + var(--g)) 50%, #0000 95%, red)
  top/100% calc(100% - var(--r)) no-repeat;

Due variabili controllano la forma. Il --g variabile non è altro che il gap di griglia. Dobbiamo tenere conto dello spazio vuoto per posizionare correttamente i nostri cerchi in modo che si sovrappongano perfettamente quando l'intero puzzle è assemblato. Il --r variabile controlla la dimensione delle parti circolari della forma del puzzle.

Griglia CSS e forme personalizzate, parte 1 PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
Griglia CSS e forme personalizzate, parte 1

Ora prendiamo lo stesso CSS e aggiorniamo alcuni valori in esso per creare le altre tre forme:

Abbiamo le forme, ma non i bordi sovrapposti di cui abbiamo bisogno per farli combaciare. Ogni immagine è limitata alla cella della griglia in cui si trova, quindi ha senso il motivo per cui le forme sono un po' confuse al momento:

Griglia CSS e forme personalizzate, parte 1 PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
Griglia CSS e forme personalizzate, parte 1

Abbiamo bisogno di creare un overflow aumentando l'altezza/larghezza delle immagini. Dalla figura sopra, dobbiamo aumentare l'altezza della prima e della quarta immagine mentre aumentiamo la larghezza della seconda e della terza. Probabilmente hai già intuito che dobbiamo aumentarli usando il --r variabile.

.gallery > img:is(:nth-child(1),:nth-child(4)) {
  width: 100%;
  height: calc(100% + var(--r));
}
.gallery > img:is(:nth-child(2),:nth-child(3)) {
  height: 100%;
  width: calc(100% + var(--r));
}

Ci stiamo avvicinando!

Abbiamo creato la sovrapposizione ma, per impostazione predefinita, le nostre immagini si sovrappongono a destra (se aumentiamo la larghezza) o in basso (se aumentiamo l'altezza). Ma non è quello che vogliamo per la seconda e la quarta immagine. La soluzione è usare place-self: end su quelle due immagini e il nostro codice completo diventa questo:

Ecco un altro esempio in cui sto usando un gradiente conico invece di un gradiente radiale. Questo ci dà pezzi di puzzle triangolari pur mantenendo lo stesso HTML e CSS sottostanti.

Un ultimo! Questa volta sto usando clip-path e poiché è una proprietà che possiamo animare, otteniamo un bel passaggio del mouse semplicemente aggiornando la proprietà personalizzata che controlla la forma.

Concludendo

Questo è tutto per questa prima parte! Combinando le cose che abbiamo già imparato su CSS Grid con alcune aggiunte clip-path ed mask magic, siamo stati in grado di creare layout a griglia con diversi tipi di forme. E abbiamo usato lo stesso markup HTML ogni volta! E il markup stesso non è altro che un contenitore con una manciata di elementi dell'immagine!

Nella seconda parte, esploreremo griglie dall'aspetto più complesso con forme più fantasiose ed effetti al passaggio del mouse.

Ho intenzione di fare la demo dei pannelli di immagini espandibili in cui abbiamo realizzato insieme questo altro articolo:

…e trasformalo in un pannello di immagini a zig-zag! E questo è solo un esempio tra i tanti che scopriremo nel prossimo articolo.

Timestamp:

Di più da Trucchi CSS