Olgu, nii et viimane kord kui sisse registreerisime, kasutasime CSS Gridi ja kombineerisime need CSS-iga clip-path
ja mask
tehnikaid väljamõeldud kujunditega võre loomiseks.
Siin on vaid üks fantastilistest võrgustikest, mille me koos tegime:
Kas olete teiseks vooruks valmis? Töötame endiselt CSS Gridiga, clip-path
ja mask
, kuid selle artikli lõpuks jõuame erinevate viiside juurde, kuidas pilte ruudustikul korraldada, sealhulgas mõningaid rad hõljumise efekte, mis muudavad piltide vaatamiseks autentse interaktiivse kogemuse.
Ja arva ära mis? Me kasutame sama märgistus, mida kasutasime eelmisel korral. Siin see jälle:
<div class="gallery">
<img src="..." alt="...">
<img src="..." alt="...">
<img src="..." alt="...">
<img src="..." alt="...">
<!-- as many times as we want -->
</div>
Nagu eelmine artikkel, vajame ainult konteinerit, mille sees on pildid. Mitte midagi rohkemat!
Pesastatud pildiruudustik
Eelmisel korral olid meie ruudud, noh, tüüpilised pildiruudud. Peale korralike kujundite, millega me neid maskeerisime, olid need üsna tavalised sümmeetrilised ruudud, mis puudutab seda, kuidas me pilte sees paigutasime.
Proovime ruudustiku keskele pildi pesastada:
Alustuseks määrame nelja pildi jaoks 2✕2 ruudustiku:
.gallery {
--s: 200px; /* controls the image size */
--g: 10px; /* controls the gap between images */
display: grid;
gap: var(--g);
grid-template-columns: repeat(2, auto);
}
.gallery > img {
width: var(--s);
aspect-ratio: 1;
object-fit: cover;
}
Pole veel midagi keerulist. Järgmine samm on meie piltide nurga lõikamine, et luua pesastatud pildi jaoks ruum. Mul on juba üksikasjalik artikkel selle kohta kuidas nurki lõigata kasutades clip-path
ja mask
. Võite kasutada ka minu võrgugeneraator nurkade maskeerimiseks CSS-i hankimiseks.
Siin on vaja välja lõigata nurgad võrdse nurga all 90deg
. Me võime sama kasutada koonuse-gradiendi tehnika sellest artiklist, et seda teha:
.gallery > img {
mask: conic-gradient(from var(--_a), #0000 90deg, #000 0);
}
.gallery > img:nth-child(1) { --_a: 90deg; }
.gallery > img:nth-child(2) { --_a: 180deg; }
.gallery > img:nth-child(3) { --_a: 0deg; }
.gallery > img:nth-child(4) { --_a:-90deg; }
Me võiksime kasutada clip-path
meetod nurkade lõikamiseks samast artiklist, kuid gradientidega maskeerimine on siin sobivam, kuna meil on kõigi piltide jaoks sama konfiguratsioon – vajame ainult pööramist (määratletud muutujaga --_a
) efekti saavutamiseks, seega maskeerime välisservade asemel seestpoolt.
Nüüd saame paigutada pesastatud pildi maskeeritud ruumi sisse. Esmalt veendume, et meil on HTML-is viies pildielement:
<div class="gallery">
<img src="..." alt="...">
<img src="..." alt="...">
<img src="..." alt="...">
<img src="..." alt="...">
<img src="..." alt="...">
</div>
Selle sinna paigutamiseks tugineme vanale heale absoluutsele positsioneerimisele:
.gallery > img:nth-child(5) {
position: absolute;
inset: calc(50% - .5*var(--s));
clip-path: inset(calc(var(--g) / 4));
}
. inset
atribuut võimaldab meil paigutada pildi ühe deklaratsiooni abil keskele. Me teame pildi suurust (määratletud muutujaga --s
) ja me teame, et konteineri suurus on 100%. Teeme matemaatikat ja kaugus igast servast peaks olema võrdne (100% - var(--s))/2
.
Võite küsida, miks me seda kasutame clip-path
üldse siin. Kasutame seda koos pesastatud kujutisega, et luua järjepidev vahe. Kui me selle eemaldaksime, märkaksite, et kõigi piltide vahel ei ole sama vahe. Nii lõikame viiendast kujutisest natuke välja, et saada selle ümber õige vahe.
Täielik kood uuesti:
.gallery {
--s: 200px; /* controls the image size */
--g: 10px; /* controls the gap between images */
display: grid;
gap: var(--g);
grid-template-columns: repeat(2, auto);
position: relative;
}
.gallery > img {
width: var(--s);
aspect-ratio: 1;
object-fit: cover;
mask: conic-gradient(from var(--_a), #0000 90deg, #000 0);
}
.gallery > img:nth-child(1) {--_a: 90deg}
.gallery > img:nth-child(2) {--_a:180deg}
.gallery > img:nth-child(3) {--_a: 0deg}
.gallery > img:nth-child(4) {--_a:-90deg}
.gallery > img:nth-child(5) {
position: absolute;
inset: calc(50% - .5*var(--s));
clip-path: inset(calc(var(--g) / 4));
}
Nüüd võivad paljud teist samuti küsida: milleks nii keeruline värk, kui saame viimase pildi ülaosale asetada ja sellele äärise lisada? See peidaks pildid pesastatud pildi all ilma maskita, eks?
See on tõsi ja me saame järgmise:
Ei mask
Juures clip-path
. Jah, koodi on lihtne mõista, kuid sellel on väike puudus: illusiooni täiuslikuks muutmiseks peab äärise värv olema sama, mis põhitaust. See väike puudus on minu jaoks piisav, et muuta kood keerulisemaks vastutasuks tegeliku taustast sõltumatu läbipaistvuse eest. Ma ei ütle, et piirilähenemine on halb või vale. Soovitaksin seda enamikel juhtudel, kui taust on teada. Kuid me oleme siin selleks, et uurida uusi asju ja, mis kõige tähtsam, ehitada komponente, mis ei sõltu nende keskkonnast.
Proovime seekord teist kujundit:
Seekord tegime pesastatud pildi ruudu asemel ringi. Sellega on lihtne ülesanne border-radius
Kuid me peame kasutama a ringikujuline väljalõige teiste piltide jaoks. Seekord aga tugineme a radial-gradient()
asemel a conic-gradient()
et saada ilus ümar välimus.
.gallery > img {
mask:
radial-gradient(farthest-side at var(--_a),
#0000 calc(50% + var(--g)/2), #000 calc(51% + var(--g)/2));
}
.gallery > img:nth-child(1) { --_a: calc(100% + var(--g)/2) calc(100% + var(--g)/2); }
.gallery > img:nth-child(2) { --_a: calc(0% - var(--g)/2) calc(100% + var(--g)/2); }
.gallery > img:nth-child(3) { --_a: calc(100% + var(--g)/2) calc(0% - var(--g)/2); }
.gallery > img:nth-child(4) { --_a: calc(0% - var(--g)/2) calc(0% - var(--g)/2); }
Kõik pildid kasutavad sama konfiguratsiooni nagu eelmises näites, kuid värskendame iga kord keskpunkti.
Ülaltoodud joonis illustreerib iga ringi keskpunkti. Siiski märkate tegelikus koodis, et ma võtan arvesse ka tühimikku, tagamaks, et kõik punktid oleksid samas kohas (ruudustiku keskel), et saada pidev ring, kui neid kombineerida.
Nüüd, kui meil on paigutus olemas, räägime hõljumise efektist. Kui te ei märganud, suurendab lahe hõljumise efekt pesastatud pildi suurust ja kohandab kõike muud vastavalt. Suuruse suurendamine on suhteliselt lihtne ülesanne, kuid gradiendi värskendamine on keerulisem, kuna vaikimisi ei saa gradiente animeerida. Selle ületamiseks kasutan a font-size
häkkida, et saaks animeerida radiaalset gradienti.
Kui kontrollite gradiendi koodi, näete, et ma lisan 1em
:
mask:
radial-gradient(farthest-side at var(--_a),
#0000 calc(50% + var(--g)/2 + 1em), #000 calc(51% + var(--g)/2 + 1em));
See on teada em
ühikud on lähteelemendi suhtes suhtelised font-size
, muutes seega font-size
Euroopa .gallery
muudab ka arvutatud em
väärtus — see on nipp, mida me kasutame. Me animeerime font-size
väärtusest 0
etteantud väärtusele ja selle tulemusena animeeritakse gradient, muutes väljalõigatud osa suuremaks, järgides järjest suuremaks muutuva pesastatud pildi suurust.
Siin on kood, mis tõstab esile hõljumise efektiga seotud osad:
.gallery {
--s: 200px; /* controls the image size */
--g: 10px; /* controls the gaps between images */
font-size: 0; /* initially we have 1em = 0 */
transition: .5s;
}
/* we increase the cut-out by 1em */
.gallery > img {
mask:
radial-gradient(farthest-side at var(--_a),
#0000 calc(50% + var(--g)/2 + 1em), #000 calc(51% + var(--g)/2 + 1em));
}
/* we increase the size by 2em */
.gallery > img:nth-child(5) {
width: calc(var(--s) + 2em);
}
/* on hover 1em = S/5 */
.gallery:hover {
font-size: calc(var(--s) / 5);
}
. font-size
trikk on kasulik, kui tahame animeerida gradiente või muid omadusi, mida ei saa animeerida. @property defineeritud kohandatud atribuudid võivad sellise probleemi lahendada, kuid toetust sellele on kirjutamise ajal veel puudulik.
Ma avastasin font-size
trikk pärit @ SelenIT2 püüdes lahendada väljakutse Twitteris.
Teine kuju? Lähme!
Seekord lõikasime pesastatud pildi rombikujuliseks. Lasen teil koodi harjutusena lahti mõtestada, et aru saada, kuidas me siia jõudsime. Märkate, et struktuur on sama, mis meie näidetes. Ainsad erinevused seisnevad selles, kuidas me kuju loomiseks gradienti kasutame. Süvene ja õpi!
Ringikujuline pildiruudustik
Saame kombineerida siin ja eelmistes artiklites õpitut, et luua veelgi põnevam pildiruudustik. Seekord muudame kõik meie ruudustikus olevad pildid ringikujuliseks ja hõljutades pilti laiendame, et paljastada kogu asi, kuna see katab ülejäänud fotod.
Ruudustiku HTML- ja CSS-struktuur pole midagi uut, nii et jätkem see osa vahele ja keskendume selle asemel soovitud ringikujulisele kujule ja hõljutusefektile.
Me hakkame kasutama clip-path
ja selle circle()
funktsiooni — arvasite ära! — lõika piltidest ring välja.
See joonis illustreerib clip-path
kasutatud esimese pildi jaoks. Vasak pool näitab pildi algolekut, paremal aga hõljutatud olekut. Sa võid kasutada see online-tööriist mängida ja visualiseerida clip-path
väärtused.
Teiste piltide puhul saame värskendada ringi keskpunkti (70% 70%
), et saada järgmine kood:
.gallery > img:hover {
--_c: 50%; /* same as "50% at 50% 50%" */
}
.gallery > img:nth-child(1) {
clip-path: circle(var(--_c, 55% at 70% 70%));
}
.gallery > img:nth-child(2) {
clip-path: circle(var(--_c, 55% at 30% 70%));
}
.gallery > img:nth-child(3) {
clip-path: circle(var(--_c, 55% at 70% 30%));
}
.gallery > img:nth-child(4) {
clip-path: circle(var(--_c, 55% at 30% 30%));
}
Pange tähele, kuidas me määratleme clip-path
väärtusi kui tagavara sees var()
. See võimaldab meil hõljutades väärtust hõlpsamini värskendada, määrates väärtuse --_c
muutuv. Kasutamisel circle()
, on keskpunkti vaikeasend 50% 50%
, seega jätame selle täpsema koodi saamiseks välja. Sellepärast näete, et me alles häälestame 50%
asemel 50% at 50% 50%
.
Seejärel suurendame hõljutatava pildi suurust ruudustiku üldise suuruseni, et saaksime katta teised pildid. Samuti tagame z-index
on hõljutatud pildil kõrgem väärtus, seega on see meie seas kõrgeim konteksti virnastamine.
.gallery {
--s: 200px; /* controls the image size */
--g: 8px; /* controls the gap between images */
display: grid;
grid: auto-flow var(--s) / repeat(2, var(--s));
gap: var(--g);
}
.gallery > img {
width: 100%;
aspect-ratio: 1;
cursor: pointer;
z-index: 0;
transition: .25s, z-index 0s .25s;
}
.gallery > img:hover {
--_c: 50%; /* change the center point on hover */
width: calc(200% + var(--g));
z-index: 1;
transition: .4s, z-index 0s;
}
.gallery > img:nth-child(1){
clip-path: circle(var(--_c, 55% at 70% 70%));
place-self: start;
}
.gallery > img:nth-child(2){
clip-path: circle(var(--_c, 55% at 30% 70%));
place-self: start end;
}
.gallery > img:nth-child(3){
clip-path: circle(var(--_c, 55% at 70% 30%));
place-self: end start;
}
.gallery > img:nth-child(4){
clip-path: circle(var(--_c, 55% at 30% 30%));
place-self: end;
}
Mis toimub koos
place-self
vara? Miks me seda vajame ja miks on igal pildil konkreetne väärtus?
Kas mäletate probleemi, mis meil eelmises artiklis tekkis pusletükkide ruudustiku loomine? Suurendasime piltide suurust ületäitumise tekitamiseks, kuid mõne pildi ületäitmine oli vale. Parandasime need kasutades place-self
vara.
Sama teema siin. Suurendame piltide suurust, nii et igaüks täidaks oma ruudustiku lahtreid. Aga kui me midagi ei tee, voolavad need kõik ruudustiku paremal ja alumisel küljel üle. Mida me vajame, on:
- esimene pilt, mis ületab parema alaserva (vaikekäitumine),
- teine pilt, mis ületab vasaku alaserva,
- kolmas pilt, mis ületab parema ülaserva, ja
- neljas pilt, mis ületab vasaku ülaserva.
Selle saamiseks peame iga pildi õigesti paigutama, kasutades place-self
vara.
Kui te pole tuttav place-self
, see on lühend sõnale justify-self
ja align-self
elemendi paigutamiseks horisontaalselt ja vertikaalselt. Kui see võtab ühe väärtuse, kasutavad mõlemad joondused sama väärtust.
Pildipaneelide laiendamine
Eelmises artiklis, lõin laheda suumiefekti, mis kehtib piltide ruudustikule, kus saame juhtida kõike: ridade arvu, veergude arvu, suurusi, mõõtkava jne.
Erijuhtum oli klassikalised laienevad paneelid, kus meil on ainult üks rida ja täislaius konteiner.
Võtame selle näite ja kombineerime selle kujunditega!
Enne jätkamist soovitan tungivalt lugeda minu teine artikkel et mõista, kuidas toimivad nipid, mida kavatseme katta. Kontrollige seda ja jätkame siin, et keskenduda paneelikujude loomisele.
Alustuseks lihtsustame koodi ja eemaldame mõned muutujad
Meil on vaja ainult ühte rida ja veergude arvu tuleks kohandada vastavalt piltide arvule. See tähendab, et me ei vaja enam ridade arvu jaoks muutujaid (--n
) ja veerud (--m
), kuid me peame kasutama grid-auto-flow: column
, mis võimaldab ruudustikul uute piltide lisamisel automaatselt veerge genereerida. Arvestame oma konteineri fikseeritud kõrgusega; vaikimisi on see täislaius.
Lõikame pildid viltu:
Jällegi on iga pilt selle ruudustiku lahtris, nii et piltide vahel on rohkem ruumi, kui me sooviksime:
Peame suurendama piltide laiust, et luua kattumist. Me asendame min-width:
100%
koos min-width: calc(100% + var(--s))
, Kus --s
on uus muutuja, mis juhib kuju.
Nüüd peame parandama esimese ja viimase pildi, nii et need eralduvad lehelt ilma lünkadeta. Teisisõnu saame eemaldada kalde esimese pildi vasakust servast ja kalde viimase pildi paremast servast. Vajame uut clip-path
spetsiaalselt nende kahe pildi jaoks.
Samuti peame parandama ülevoolu. Vaikimisi täituvad kõik pildid mõlemalt poolt, kuid esimese pildi jaoks vajame ületäitumist paremal, samas kui viimase pildi jaoks vajame vasakpoolset ületäitumist.
.gallery > img:first-child {
min-width: calc(100% + var(--s)/2);
place-self: start;
clip-path: polygon(0 0,100% 0,calc(100% - var(--s)) 100%,0 100%);
}
.gallery > img:last-child {
min-width: calc(100% + var(--s)/2);
place-self: end;
clip-path: polygon(var(--s) 0,100% 0,100% 100%,0 100%);
}
Lõpptulemus on kena laienev kaldus piltide paneel!
Saame lisada nii palju pilte kui soovite ja ruudustik kohandub automaatselt. Lisaks peame kuju kontrollimiseks juhtima ainult ühte väärtust!
Sama paigutuse oleksime võinud teha ka flexboxiga, kuna tegemist on ühe elementide reaga. Siin on minu teostus.
Muidugi, kaldus pildid on lahedad, aga kuidas on lood siksakilise mustriga? Ma juba kiusasin seda viimase artikli lõpp.
Kõik, mida ma siin teen, on asendamine clip-path
koos mask
… ja arva ära mis? Mul on juba üksikasjalik artikkel selle kohta selle siksakilise kuju loomine - Internetist rääkimata generaator koodi saamiseks. Vaata, kuidas kõik kokku saab?
Kõige keerulisem on siin tagada, et sik-sakid oleksid ideaalselt joondatud, ja selleks peame lisama igale nihkele :nth-child(odd)
pildi element.
.gallery > img {
mask:
conic-gradient(from -135deg at right, #0000, #000 1deg 89deg, #0000 90deg)
100% calc(50% + var(--_p, 0%))/51% calc(2*var(--s)) repeat-y,
conic-gradient(from 45deg at left, #0000, #000 1deg 89deg, #0000 90deg)
0% calc(50% + var(--_p, 0%))/51% calc(2*var(--s)) repeat-y;
}
/* we add an offset to the odd elements */
.gallery > img:nth-child(odd) {
--_p: var(--s);
}
.gallery > img:first-child {
mask:
conic-gradient(from -135deg at right, #0000, #000 1deg 89deg, #0000 90deg)
0 calc(50% + var(--_p, 0%))/100% calc(2*var(--s));
}
.gallery > img:last-child {
mask:
conic-gradient(from 45deg at left, #0000, #000 1deg 89deg, #0000 90deg)
0 calc(50% + var(--_p, 0%)) /100% calc(2*var(--s));
}
Pange tähele, et kasutada --_p
muutuja, mis langeb tagasi 0%
kuid on võrdne --_s
veidrate piltide jaoks.
Siin on demo, mis illustreerib probleemi. Hõljutage kursorit, et näha, kuidas nihe on määratletud --_p
— fikseerib joonduse.
Samuti pange tähele, kuidas me kasutame esimese ja viimase pildi jaoks erinevat maski, nagu tegime eelmises näites. Vajame ainult sik-saki esimese pildi paremale ja viimase pildi vasakule küljele.
Ja miks mitte ümarad küljed? Teeme seda!
Ma tean, et kood võib tunduda hirmutav ja raskesti mõistetav, kuid kõik, mis toimub, on kombinatsioon erinevatest nippidest, mida oleme käsitlenud selles ja teistes artiklites, mida olen juba jaganud. Sel juhul kasutan sama koodistruktuuri nagu sik-sak ja kaldus kujundid. Võrrelge seda nende näidetega ja te ei leia mingit erinevust! Need on samad nipid minu eelmine artikkel suumiefekti kohta. Siis ma kasutan oma muud kirjatööd ja minu võrgugeneraator et saada kood neid ümaraid kujundeid loova maski jaoks.
Kui mäletate, mida me sik-saki jaoks tegime, olime kasutanud kõigi piltide jaoks sama maski, kuid pidime seejärel lisama paaritutele piltidele nihke, et luua täiuslik kattumine. Sel juhul vajame paaritute arvudega piltide jaoks teistsugust maski.
Esimene mask:
mask:
linear-gradient(-90deg,#0000 calc(2*var(--s)),#000 0) var(--s),
radial-gradient(var(--s),#000 98%,#0000) 50% / calc(2*var(--s)) calc(1.8*var(--s)) space repeat;
Teine:
mask:
radial-gradient(calc(var(--s) + var(--g)) at calc(var(--s) + var(--g)) 50%,#0000 98% ,#000)
calc(50% - var(--s) - var(--g)) / 100% calc(1.8*var(--s))
Ainus pingutus, mida ma siin tegin, on teise maski värskendamine, et lisada lünkmuutuja (--g
), et luua piltide vahele see ruum.
Viimane puudutus on esimese ja viimase pildi parandamine. Nagu kõik eelnevad näited, vajab esimene pilt sirget vasakut serva, viimane aga sirget paremat serva.
Esimese pildi puhul teame alati maski, mis sellel peab olema, mis on järgmine:
.gallery > img:first-child {
mask:
radial-gradient(calc(var(--s) + var(--g)) at right, #0000 98%, #000) 50% / 100% calc(1.8 * var(--s));
}
Viimase pildi puhul sõltub see elementide arvust, seega on oluline, kas see element on :nth-child(odd)
or :nth-child(even)
.
.gallery > img:last-child:nth-child(even) {
mask:
linear-gradient(to right,#0000 var(--s),#000 0),
radial-gradient(var(--s),#000 98%,#0000) left / calc(2*var(--s)) calc(1.8*var(--s)) repeat-y
}
.gallery > img:last-child:nth-child(odd) {
mask:
radial-gradient(calc(var(--s) + var(--g)) at left,#0000 98%,#000) 50% / 100% calc(1.8*var(--s))
}
See on kõik! Kolm erinevat paigutust, kuid iga kord samad CSS-i nipid:
- koodi struktuur suumiefekti loomiseks
- kujundite loomiseks mask või klipptee
- mõnel juhul eraldi konfiguratsiooni paaritute elementide jaoks, et tagada täiuslik kattumine
- konkreetne konfiguratsioon esimese ja viimase pildi jaoks, et hoida kuju ainult ühel küljel.
Ja siin on suur demo nende kõigiga koos. Kõik, mida vajate, on lisada klass, et aktiveerida paigutus, mida soovite näha.
Ja siin on üks Flexboxi juurutusega
Pakke kuni
Oeh, oleme valmis! Ma tean, et selle artikli ja viimase vahel on palju CSS-i nippe ja näiteid, rääkimata kõigist muudest nippidest, millele olen siin viidanud teistes kirjutatud artiklites. Mul läks aega, et kõik kokku panna ja kõike ei pea korraga aru saama. Üks lugemine annab teile hea ülevaate kõigist paigutustest, kuid võib-olla peate artiklit rohkem kui korra läbi lugema ja keskenduma igale näitele, et mõista kõiki nippe.
Kas märkasite, et me ei puudutanud HTML-i üldse peale märgistuses olevate piltide arvu? Kõik meie tehtud paigutused jagavad sama HTML-koodi, mis pole muud kui piltide loend.
Enne lõpetamist toon teile viimase näite. See on laheda hõljumise efektiga "versus" kahe animetegelase vahel.
Aga sina? Kas saate õpitu põhjal midagi luua? See ei pea olema keeruline – kujutage ette midagi lahedat või naljakat, nagu tegin selle animemänguga. See võib olla teile hea harjutus ja me võime lõpetada kommentaaride jaotises suurepärase kogumikuga.