CSS-gitter og brugerdefinerede former, del 1 PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

CSS-gitter og brugerdefinerede former, del 1

I en tidligere artikel så jeg på CSS Grids evne til at skabe komplekse layouts ved hjælp af dens autoplaceringsbeføjelser. Jeg tog det et skridt videre i en anden artikel tilføjet en zoomende hover-effekt til billeder i et gitterlayout. Denne gang vil jeg dykke ned i en anden type gitter, en der arbejder med former.

Hvad hvis billederne ikke er helt firkantede, men i stedet er formet som sekskanter eller romber? Spoiler alert: vi kan gøre det. Faktisk vil vi kombinere CSS Grid-teknikker, vi har set på, og droppe nogle CSS clip-path , mask magi til at skabe smarte gitter af billeder til næsten enhver form, du kan forestille dig!

Lad os starte med noget opmærkning

De fleste af de layouts, vi skal se på, ser måske nemme ud at opnå ved første øjekast, men den udfordrende del er at opnå dem med den samme HTML-markering. Vi kan bruge mange indpakninger, divs, og hvad der så, men målet med dette indlæg er at bruge den samme og mindste mængde HTML-kode og stadig få alle de forskellige gitter, vi ønsker. Når alt kommer til alt, hvad er CSS end en måde at adskille styling og markup på? Vores styling bør ikke afhænge af markeringen og omvendt.

Når det er sagt, lad os starte med dette:

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

En beholder med billeder er alt, hvad vi har brug for her. Intet mere!

CSS Grid of Hexagons

Dette omtales også nogle gange som et "honningkage"-gitter.

Der er allerede masser af andre blogindlæg derude, der viser, hvordan man laver dette. For pokker, jeg skrev en her på CSS-Tricks! Den artikel er stadig god og går meget i dybden med at lave et responsivt layout. Men for dette specifikke tilfælde vil vi stole på en meget enklere CSS-tilgang.

Først, lad os bruge clip-path på billederne for at skabe den sekskantede form, og vi placerer dem alle i det samme gitterområde, så de overlapper hinanden.

.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%)

Ikke noget fancy endnu. Alle billederne er sekskanter og over hinanden. Så det ser ud til, at alt vi har er et enkelt sekskantformet billedelement, men der er virkelig syv.

Det næste trin er at anvende en oversættelse til billederne for at placere dem korrekt på gitteret.

CSS-gitter og brugerdefinerede former, del 1 PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
CSS-gitter og brugerdefinerede former, del 1

Bemærk, at vi stadig ønsker, at et af billederne skal forblive i midten. Resten placeres omkring det ved hjælp af CSS translate og god gammeldags geometri. Her er de falske formler, jeg fandt på for hvert billede i gitteret:

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))

Et par beregninger og optimering senere (lad os springe den kedelige del over, ikke?) får vi følgende 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)); }

Måske bliver det nemmere, når vi får det reelle trigonometrifunktioner i CSS!

Hvert billede er oversat af --_x , --_y variabler, der er baseret på disse formler. Kun det andet billede (nth-child(2)) er udefineret i enhver vælger, fordi det er den i midten. Det kan være et hvilket som helst billede, hvis du beslutter dig for at bruge en anden rækkefølge. Her er den rækkefølge, jeg bruger:

CSS-gitter og brugerdefinerede former, del 1 PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
CSS-gitter og brugerdefinerede former, del 1

Med kun et par linjer kode får vi et sejt gitter af billeder. Til dette tilføjede jeg en lille hover-effekt til billederne for at gøre tingene mere avancerede.

Gæt hvad? Vi kan få endnu et sekskantet gitter ved blot at opdatere nogle få værdier.

Hvis du tjekker koden og sammenligner den med den forrige, vil du bemærke, at jeg simpelthen har byttet værdierne indeni clip-path og jeg skiftede mellem --x , --y. Det er alt!

CSS Grid of Rhombuses

Rhombus er sådan et fancy ord for en firkant, der er roteret 45 grader.

Samme HTML, husker du? Vi starter først med at definere et 2×2 gitter af billeder i 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;
}

Den første ting, der kan fange dit øje, er grid ejendom. Det er temmelig ualmindeligt brugt, men er super nyttigt, fordi det er en stenografi, der lader dig definere et komplet gitter i én erklæring. Det er ikke den mest intuitive - og for ikke at nævne læsbare - ejendom, men vi er her for at lærer , opdage nye ting, så lad os bruge det i stedet for at skrive alle de individuelle grid-egenskaber ud.

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

Dette definerer to kolonner svarende til --s variabel og indstiller højden på alle rækkerne til --s såvel. Da vi har fire billeder, får vi automatisk et 2×2-gitter.

Her er en anden måde, vi kunne have skrevet det på:

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

…som kan reduceres med grid stenografi:

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

Efter indstilling af gitteret roterer vi det og billederne med CSS transforms og vi får dette:

Bemærk, hvordan jeg roterer dem begge ved 45deg, men i den modsatte retning.

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

Rotation af billederne i negativ retning forhindrer dem i at blive roteret med gitteret, så de forbliver lige. Nu anvender vi en clip-path at klippe en rombeform ud af dem.

CSS-gitter og brugerdefinerede former, del 1 PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%)

Vi er næsten færdige! Vi skal rette størrelsen på billedet for at få dem til at passe sammen. Ellers er de placeret langt fra hinanden til det punkt, hvor det ikke ligner et gitter af billeder.

CSS-gitter og brugerdefinerede former, del 1 PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
CSS-gitter og brugerdefinerede former, del 1

Billedet er inden for grænsen af ​​den grønne cirkel, som er den indskrevne cirkel i det gitterområde, hvor billedet er placeret. Det, vi ønsker, er at gøre billedet større, så det passer ind i den røde cirkel, som er den omskrevne cirkel af gitterområdet.

Bare rolig, jeg vil ikke introducere mere kedelig geometri. Alt du behøver at vide er, at forholdet mellem radius af hver cirkel er kvadratroden af ​​2 (sqrt(2)). Dette er den værdi, vi har brug for for at øge størrelsen på vores billeder for at fylde området. Vi vil bruge 100%*sqrt(2) = 141% og være færdig!

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

Ligesom det sekskantede gitter kan vi gøre tingene mere avancerede med den flotte zoomende svæveeffekt:

CSS-gitter af trekantede former

Du ved sikkert efterhånden, at det store trick er at finde ud af clip-path at få de former, vi ønsker. For dette gitter har hvert element sit eget clip-path værdi, hvorimod de sidste to gitre arbejdede med en ensartet form. Så denne gang er det som om, vi arbejder med et par forskellige trekantede former, der samles for at danne et rektangulært gitter af billeder.

CSS-gitter og brugerdefinerede former, del 1 PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
De tre billeder øverst
CSS-gitter og brugerdefinerede former, del 1 PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
De tre billeder nederst

Vi placerer dem inde i et 3×2 gitter med følgende 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%); } }

Her er hvad vi får:

Den sidste berøring er at gøre bredden af ​​den midterste søjle ens 0 for at slippe af med mellemrummene mellem billederne. Den samme slags afstandsproblem, som vi havde med rombegitteret, men med en anden tilgang til de former, vi bruger:

grid-template-columns: auto 0 auto;

Jeg var nødt til at rode med clip-path værdier for at sikre, at de alle ser ud til at passe fint sammen som et puslespil. De originale billeder overlapper hinanden, når den midterste kolonne har nul bredde, men efter at have skåret billederne ud, er illusionen perfekt:

CSS-gitter og brugerdefinerede former, del 1 PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
CSS-gitter og brugerdefinerede former, del 1

CSS Pizza Pie Grid

Gæt hvad? Vi kan få endnu et fedt gitter ved blot at tilføje border-radius , overflow til vores gitter eller trekantede former. 🎉

CSS-gitter af puslespilsbrikker

Denne gang skal vi spille med CSS mask egenskab for at få billederne til at ligne brikker af et puslespil.

Hvis du ikke har brugt mask med CSS-gradienter, Jeg kan varmt anbefale denne anden artikel Jeg skrev om emnet, fordi det vil hjælpe med det næste. Hvorfor gradienter? For det er det, vi bruger til at få de runde hak i puslespilsbrikkernes former.

Opsætningen af ​​gitteret burde være let nu, så lad os i stedet fokusere på mask en del.

Som illustreret i ovenstående demo, har vi brug for to gradienter for at skabe den endelige form. Den ene gradient skaber en cirkel (den grønne del), og den anden skaber den rigtige kurve, mens den øverste del udfyldes.

--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;

To variable styrer formen. Det --g variabel er intet andet end gittergabet. Vi skal tage højde for hullet for at placere vores cirkler korrekt, så de overlapper perfekt, når hele puslespillet er samlet. Det --r variabel styrer størrelsen af ​​cirkulære dele af puslespillet.

CSS-gitter og brugerdefinerede former, del 1 PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
CSS-gitter og brugerdefinerede former, del 1

Nu tager vi den samme CSS og opdaterer et par værdier i den for at skabe de tre andre former:

Vi har formerne, men ikke de overlappende kanter, vi skal bruge for at få dem til at passe sammen. Hvert billede er begrænset til den gittercelle, det er i, så det giver mening, hvorfor formerne er lidt rodede i øjeblikket:

CSS-gitter og brugerdefinerede former, del 1 PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
CSS-gitter og brugerdefinerede former, del 1

Vi skal skabe et overløb ved at øge højden/bredden på billederne. Fra ovenstående figur skal vi øge højden på det første og fjerde billede, mens vi øger bredden på det andet og tredje billede. Du har sikkert allerede gættet, at vi skal øge dem ved hjælp af --r variabel.

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

Vi kommer tættere på!

Vi oprettede overlapningen, men som standard overlapper vores billeder enten til højre (hvis vi øger bredden) eller bunden (hvis vi øger højden). Men det er ikke det, vi ønsker for andet og fjerde billede. Rettelsen er at bruge place-self: end på disse to billeder, og vores fulde kode bliver denne:

Her er et andet eksempel, hvor jeg bruger en konisk gradient i stedet for en radial gradient. Dette giver os trekantede puslespilsbrikker, mens vi beholder den samme underliggende HTML og CSS.

En sidste en! Denne gang bruger jeg clip-path og da det er en egenskab, vi kan animere, får vi et cool svæv ved blot at opdatere den brugerdefinerede egenskab, der styrer formen.

Indpakning op

Det var alt for denne første del! Ved at kombinere de ting, vi allerede har lært om CSS Grid med nogle tilføjede clip-path , mask magi, var vi i stand til at lave gitterlayouts med forskellige former for former. Og vi brugte den samme HTML-markering hver gang! Og selve opmærkningen er ikke andet end en beholder med en håndfuld billedelementer!

I den anden del skal vi udforske mere komplekst udseende net med mere fancy former og svæveeffekter.

Jeg planlægger at tage demoen af ​​udvidede billedpaneler, vi lavede sammen i denne anden artikel:

…og forvandle det til et zig-zag billedpanel! Og dette er kun et eksempel blandt de mange, vi vil opdage i den næste artikel.

Tidsstempel:

Mere fra CSS-tricks