Zoom af billeder i et gitterlayout PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Zoom af billeder i et gitterlayout

Det er nemt at oprette et gitter af billeder takket være CSS Grid. Men at få nettet til at gøre smarte ting efter billederne er blevet placeret kan være vanskelige at få af.

Sig, at du vil tilføje en fancy svæveeffekt til billederne, hvor de vokser og zoome ud over rækkerne og kolonnerne, hvor de sidder? Vi kan gøre det!

Fedt, ikke? Hvis du tjekker koden, vil du ikke finde noget JavaScript, komplekse vælgere eller endda magiske tal. Og dette er kun et eksempel blandt mange, vi vil udforske!

Opbygning af nettet

HTML-koden til at oprette gitteret er så simpel som en liste over billeder i en container. Vi har ikke brug for mere end det.

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

For CSS starter vi først med at indstille gitteret ved hjælp af følgende:

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

Kort sagt har vi to variabler, en der styrer størrelsen på billederne og en der sætter størrelsen på afstanden mellem billederne. aspect-ratio hjælper med at holde tingene i proportion.

Du undrer dig måske over, hvorfor vi kun definerer tre kolonner, men ingen rækker. Nej, jeg har ikke glemt rækkerne - vi behøver bare ikke udtrykkeligt at angive dem. CSS Grid er i stand til automatisk at placere elementer på implicitte rækker og kolonner, hvilket betyder, at vi får så mange rækker som nødvendigt til et hvilket som helst antal billeder, vi kaster efter det. Vi kan udtrykkeligt definere rækkerne i stedet, men vi skal tilføje grid-auto-flow: column for at sikre, at browseren opretter de nødvendige kolonner for os.

Her er et eksempel for at illustrere begge tilfælde. Forskellen er, at man flyder i en row retning og den anden i en column retning.

Til betaling denne anden artikel skrev jeg for mere om de implicitte gitter og den automatiske placeringsalgoritme.

Nu hvor vi har vores gitter, er det tid til at style billederne:

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

Hover-effekten, vi laver, afhænger af denne CSS. Det ser sikkert mærkeligt ud for dig, at vi laver billeder, der både ikke har nogen bredde eller højde, men som har en minimumsbredde og -højde på 100 %. Men du vil se, at det er et ret smart trick til det, vi forsøger at opnå.

Det, jeg gør her, er at fortælle browseren, at billederne skal have 0 bredde og højde, men skal også have en minimumshøjde svarende til 100%… men 100% af hvad? Ved brug af procenter er værdien i forhold til noget andet. I dette tilfælde er vores billede placeret inde i en gittercelle og vi skal kende den størrelse for at vide, hvad der er 100% er i forhold til.

Browseren vil først ignorere min-height: 100% til at beregne størrelsen af ​​gittercellerne, men den vil bruge height: 0 i sin beregning. Det betyder, at vores billeder ikke vil bidrage til størrelsen af ​​gittercellerne... fordi de teknisk set ikke har nogen fysisk størrelse. Dette vil resultere i tre lige store kolonner og rækker, der er baseret på størrelsen af ​​gitteret (som vi definerede på .gallery's bredde og aspect-ratio). Højden af ​​hver gittercelle er intet andet end variablen --s vi definerede (samme for bredden).

Zoom af billeder i et gitterlayout

Nu hvor vi har dimensionerne af vores gitters celler, vil browseren bruge det med min-height: 100% (Og min-width: 100%), hvilket vil tvinge billederne til at fylde hele rummet i hver gittercelle. Det hele kan se lidt forvirrende ud, men hovedideen er at sikre, at gitteret definerer størrelsen af ​​billederne i stedet for omvendt. Jeg ønsker ikke, at billedet skal definere størrelsen af ​​gitteret, og du vil forstå hvorfor efter at have tilføjet svæveeffekten.

Oprettelse af svæveeffekten

Det, vi skal gøre, er at øge skalaen af ​​billederne, når de svæver. Det kan vi gøre ved at justere et billedes width , 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));
}

Jeg tilføjede en ny tilpasset variabel, --f, til blandingen som en skaleringsfaktor for at kontrollere størrelsen ved svævning. Bemærk, hvordan jeg multiplicerer størrelsesvariablen, --s, ved at beregne den nye billedstørrelse.

Men du sagde, at billedstørrelsen skal være 0. Hvad sker der? Jeg er faret vild…

Det, jeg sagde, er stadig sandt, men jeg gør en undtagelse for det svævede billede. Jeg fortæller browseren, at kun ét billede vil have en størrelse, der ikke er lig med nul - så det vil bidrage til dimensionen af ​​gitteret - mens alle de andre forbliver lig med 0.

Zoom af billeder i et gitterlayout PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
Zoom af billeder i et gitterlayout

Venstre side viser gitteret i dets naturlige tilstand uden nogen svævende billeder, hvilket er hvad højre side viser. Alle gittercellerne på venstre side er lige store, da alle billederne ikke har nogen fysiske dimensioner.

På højre side svæver det andet billede i første række, hvilket giver det dimensioner, der påvirker gittercellens størrelse. Browseren vil gøre den specifikke gittercelle større ved svævning, hvilket bidrager til den samlede størrelse. Og da størrelsen på hele gitteret er indstillet (fordi vi sætter en fast width på den .gallery), vil de andre gitterceller logisk reagere ved at blive mindre for at beholde .gallery's samlede størrelse i takt.

Det er vores zoom-effekt i aktion! Ved at øge størrelsen på kun ét billede påvirker vi hele gitterkonfigurationen, og vi sagde før, at gitteret definerer størrelsen på billederne, så hvert billede strækker sig inde i sin gittercelle for at fylde hele rummet.

Hertil tilføjer vi et strejf af transition Og brug object-fit for at undgå billedforvrængning og illusionen er perfekt!

Jeg ved, at logikken bag tricket ikke er let at forstå. Bare rolig, hvis du ikke helt forstår det. Det vigtigste er at forstå strukturen af ​​den anvendte kode, og hvordan man ændrer den for at få flere variationer. Det er det, vi vil gøre næste gang!

Tilføjelse af flere billeder

Vi lavede et 3×3-gitter for at forklare hovedtricket, men du har sikkert gættet, at vi ikke behøver at stoppe der. Vi kan lave antallet af kolonner og rækker til variable og tilføje så mange billeder, som vi vil.

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

Vi har to nye variabler for antallet af rækker og kolonner. Så definerer vi blot bredden og højden af ​​vores gitter ved hjælp af dem. Samme for grid-template-columns som bruger --m variabel. Og ligesom før behøver vi ikke eksplicit at definere rækkerne, da CSS Grids autoplaceringsfunktion vil gøre arbejdet for os, uanset hvor mange billedelementer vi bruger.

Hvorfor ikke forskellige værdier for bredden og højden? Vi kan gøre det:

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

Vi erstatter --s med to variable, en for bredden, --w, og en anden for højden, --h. Så tilpasser vi alt andet derefter.

Så vi startede med et gitter med en fast størrelse og antal elementer, men så lavede vi et nyt sæt variabler for at få enhver konfiguration, vi ønsker. Alt, hvad vi skal gøre, er at tilføje så mange billeder, som vi vil, og justere CSS-variablerne i overensstemmelse hermed. Kombinationerne er ubegrænsede!

Hvad med en fuldskærmsversion? Ja, det er også muligt. Alt, hvad vi behøver, er at vide, hvilke værdier vi skal tildele vores variabler. Hvis vi vil N rækker af billeder, og vi ønsker, at vores gitter skal være fuldskærm, skal vi først løse for en højde på 100vh:

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

Samme logik for bredden, men vha vw i stedet for vh:

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

Vi laver regnestykket for at få:

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

Udført!

Det er den samme nøjagtige HTML, men med nogle opdaterede variabler, der ændrer gitterets størrelse og adfærd.

Bemærk, at jeg har udeladt den formel, vi tidligere har sat på .gallery's width , height og erstattede dem med 100vw , 100vh, henholdsvis. Formlen vil give os det samme resultat, men da vi ved hvilken værdi vi ønsker, kan vi droppe al den ekstra kompleksitet.

Vi kan også forenkle --h , --w ved at fjerne mellemrummet fra ligningen til fordel for dette:

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

Dette vil få det svævede billede til at vokse en smule mere end det forrige eksempel, men det er ikke så meget, da vi kan styre skalaen med --f variabel, vi bruger som multiplikator.

Og da variablerne bruges ét sted, kan vi stadig forenkle koden ved at fjerne dem helt:

Det er vigtigt at bemærke, at denne optimering kun gælder for fuldskærmseksemplet og ikke for de eksempler, vi har dækket. Dette eksempel er et særligt tilfælde, hvor vi kan gøre koden lettere ved at fjerne noget af det komplekse regnearbejde, vi havde brug for i de andre eksempler.

Vi har faktisk alt, hvad vi behøver for at skabe det populære mønster af ekspanderende paneler:

Lad os grave endnu dybere

Har du bemærket, at vores skaleringsfaktor kan være mindre end 1? Vi kan definere størrelsen af ​​det svævede billede til at være mindre end --h or --w men billedet bliver større ved at svæve.

Den oprindelige gittercellestørrelse er lig med --w , --h, så hvorfor laver en mindre værdi gittercellen større? Skulle cellen ikke få mindre, eller i det mindste bevare sin oprindelige størrelse? Og hvad er den endelige størrelse af gittercellen?

Vi skal grave dybere ned i, hvordan CSS Grid-algoritmen beregner størrelsen af ​​gittercellerne. Og dette indebærer forståelse af CSS Grids standard strækjustering.

Her er et eksempel for at forstå logikken.

På venstre side af demoen definerede jeg en to-kolonne med auto bredde. Vi får det intuitive resultat: to lige store kolonner (og to lige store gitterceller). Men gitteret satte jeg op i højre side af demoen, hvor jeg opdaterer justeringen ved hjælp af place-content: start, ser ud til at have ingenting.

DevTools hjælper med at vise os, hvad der virkelig sker i begge tilfælde:

Zoom af billeder i et gitterlayout PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
Zoom af billeder i et gitterlayout

I det andet gitter har vi to kolonner, men deres bredder er lig med nul, så vi får to gitterceller, der er kollapset i øverste venstre hjørne af gitterbeholderen. Dette er ikke en fejl, men det logiske resultat af gitterets justering. Når vi dimensionerer en kolonne (eller række) med auto, betyder det, at dens indhold dikterer dens størrelse - men vi har en tom div uden indhold at give plads til.

Men siden stretch er standardjusteringen, og vi har nok plads inde i vores gitter, vil browseren strække begge gitterceller lige meget for at dække hele det område. Sådan ender gitteret til venstre op med to lige store søjler.

Fra specifikationen:

Bemærk, at visse værdier af justify-content , align-content kan få sporene til at være adskilt (space-around, space-between, space-evenly) eller skal ændres størrelse (stretch).

Bemærk "skal ændres størrelse", som er nøglen her. I det sidste eksempel brugte jeg place-content som er forkortelsen for justify-content , align-content

Og dette er begravet et sted i Grid Sizing-algoritmen specs:

Dette trin udvider spor, der har en auto max sporstørrelsesfunktion ved at dividere eventuelle resterende positive, konkret ledig plads ligeligt blandt dem. Hvis den ledige plads er ubestemt, Men gitterbeholder har en bestemt min bredde/højde, skal du bruge den størrelse til at beregne den ledige plads til dette trin i stedet for.

"Lige" forklarer, hvorfor vi ender med lige store gitterceller, men det gælder for "det frie rum", hvilket er meget vigtigt.

Lad os tage det forrige eksempel og tilføje indhold til en af ​​de divs:

Vi tilføjede en firkant 50px billede. Her er en illustration af, hvordan hvert gitter i vores eksempel reagerer på det billede:

Zoom af billeder i et gitterlayout PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
Zoom af billeder i et gitterlayout

I det første tilfælde kan vi se, at den første celle (i rødt) er større end den anden (i blåt). I det andet tilfælde ændres størrelsen af ​​den første celle, så den passer til billedets fysiske størrelse, mens den anden celle forbliver uden dimensioner. Det ledige rum er delt ligeligt, men den første celle har mere indhold indeni, hvilket gør den større.

Dette er matematikken til at finde ud af vores ledige plads:

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

Divideret med to - antallet af kolonner - får vi en bredde på 72.5px for hver kolonne. Men vi tilføjer størrelsen på billedet, 50px, til den første kolonne, som efterlader os med en kolonne kl 122.5px og den anden lig med 72.5px.

Den samme logik gælder for vores gitter af billeder. Alle billederne har en størrelse svarende til 0 (intet indhold), mens det svævede billede bidrager til størrelsen - også selvom det bare er det 1px — gør dens gittercelle større end de andre. Af denne grund kan skalafaktoren være en hvilken som helst værdi større end 0 lige decimaler imellem 0 , 1.

For at få den endelige bredde af gittercellerne laver vi den samme beregning for at få følgende:

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

Beholderens bredde er defineret af:

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

…og alle hullerne er lig med:

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

…og for det svævede billede har vi:

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

Vi kan beregne alt det med vores variable:

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

Antallet af kolonner er defineret af --m , så vi deler den ledige plads ligeligt for at få:

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

…hvilket giver os størrelsen af ​​de ikke-svævende billeder. For svævede billeder har vi dette:

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

Hvis vi ønsker at kontrollere den endelige størrelse af det svævede billede, overvejer vi ovenstående formel for at få den nøjagtige størrelse, vi ønsker. Hvis vi for eksempel ønsker, at billedet skal være dobbelt så stort:

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

Så værdien af ​​vores skalamultiplikator, --f, skal være lig med:

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

For tre kolonner vil vi have 3/2 = 1.5 og det er den skaleringsfaktor, jeg brugte i den første demo af denne artikel, fordi jeg ville gøre billedet dobbelt så stort, når jeg svæver!

Den samme logik gælder for højdeberegningen, og hvis vi ønsker at kontrollere dem begge uafhængigt, bliver vi nødt til at overveje to skalafaktorer for at sikre, at vi har en specifik bredde og højde ved svævning.

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

Nu kender du alle hemmelighederne til at skabe enhver form for billedgitter med en cool svæveeffekt, mens du også har kontrol over den størrelse, du ønsker ved hjælp af den matematik, vi lige har dækket.

Indpakning op

I min sidste artikel, skabte vi et komplekst udseende gitter med et par linjer CSS, der satte CSS Grids implicitte gitter- og autoplaceringsfunktioner i brug. I denne artikel har vi påberåbt os nogle tricks til CSS Grid-størrelsesstørrelser for at skabe et fancy gitter af billeder, der zoomer ved at svæve og får gitteret til at justere i overensstemmelse hermed. Alt dette med en forenklet kode, der er nem at justere ved hjælp af CSS-variabler!

I den næste artikel leger vi med former! Vi vil kombinere CSS-gitter med maske og clip-path for at få fancy gitter af billeder.

Tidsstempel:

Mere fra CSS-tricks