Varem pidin sageli välja mõtlema, kuidas lisada stiile kõikidele konteineris olevatele elementidele, kuid mitte hõljunud.
See efekt nõuab hõljuva elemendi õdede-vendade valimist. Kasutasin selleks JavaScripti, lisades või eemaldades klassi, mis määratles õiged CSS-i reeglid mouseenter
ja mouseleave
sarnased sündmused:
Kuigi kood ajab asja ära, ütles mu sisetunne mulle alati, et sama tulemuse saavutamiseks peab olema mingi puhas CSS-i viis. Mõned aastad tagasi oma ettevõttes teatud liuguri kallal töötades jõudsin sarnase lahenduseni kuidas Chris Geelhoed lõi kuulsa Netflixi kodulehe animatsiooni ja sain aru, et ma ei vaja selleks enam JavaScripti.
Paar kuud tagasi proovisin oma ettevõtte veebisaidil rakendada sama lähenemisviisi ruudustikupõhisele voogule ja — buum — see ei toiminud elementidevahelise tühimiku tõttu!
Minu õnneks tundus, et see ei pea niimoodi jääma ja järjekordselt polnud mul selleks JavaScripti vaja.
Märgistus ja põhi-CSS
Alustame kodeerimist, valmistades ette õige märgistuse:
.grid
on ruudustikupõhineloetelu;
- ja
.grid__child
elemendid on
lapsed, kellega tahame suhelda.
Märgistus näeb välja selline:
Stiil peaks välja nägema selline:
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, 15rem);
grid-gap: 1rem;
}
.grid__child {
background: rgba(0, 0, 0, .1);
border-radius: .5rem;
aspect-ratio: 1/1;
}
See näidiskood loob kolm loendiüksust, mis hõivavad ruudustikus kolm veergu.
CSS-i valijate võimsus
Nüüd lisame veidi interaktiivsust. Algselt rakendatud lähenemisviis põhines kahel etapil:
- konteineri peal hõljumine peaks muutma kõigi sees olevate elementide stiile…
- …välja arvatud see, mille kursor hetkel hõljub.
Alustame iga lapse haaramisega, kui kursor konteineri kohal hõljub:
.grid:hover .grid__child {
/* ... */
}
Teiseks jätame välja praegu hõljuva üksuse ja vähendame opacity
mis tahes muust lapsest:
.grid:hover .grid__child:not(:hover) {
opacity: 0.3;
}
Ja sellest piisaks täiesti konteinerite jaoks, kus alamelementide vahel pole lünki:
Kuid minu puhul ei saanud ma neid lünki eemaldada:
Kui ma hiirt plaatide vahel liigutasin, kustusid kõik lasteelemendid.
Lünkade ignoreerimine
Võime eeldada, et lüngad on konteineri osad, mida selle lapsed ei kata. Me ei taha efekti käivitada iga kord, kui kursor konteinerisse siseneb, vaid pigem siis, kui see hõljub mõne sees oleva elemendi kohal. Kas saame siis lünkade kohal liikuvat kursorit ignoreerida?
Jah, me saame kasutada pointer-events: none
kohta .grid
konteinerisse ja tuua need tagasi pointer-events: auto
selle laste peal:
.grid {
/* ... */
pointer-events: none;
}
/* ... */
.grid__child {
/* ... */
pointer-events: auto;
}
Lisame lihtsalt laheda ülemineku läbipaistmatuse kohta ja meil on valmis komponent:
Tõenäoliselt on veelgi lahedam, kui lisame rohkem plaate ja loome kahemõõtmelise paigutuse:
Lõplik CSS näeb välja selline:
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, 15rem);
grid-gap: 3rem;
pointer-events: none;
}
.grid:hover .grid__child:not(:hover) {
opacity: 0.3;
}
.grid__child {
background: rgba(0, 0, 0, .1);
border-radius: .5rem;
aspect-ratio: 1/1;
pointer-events: auto;
transition: opacity 300ms;
}
Vaid 2 täiendava koodireaga saime lünkprobleemist jagu!
Võimalikud probleemid
Kuigi see on kompaktne lahendus, on olukordi, kus see võib vajada mõningaid lahendusi.
Kahjuks see trikk ei tööta, kui soovite, et konteiner oleks keritav, nt nagu mingis horisontaalses liuguris. The pointer-events: none
stiil eiraks mitte ainult hõljumise sündmust, vaid ka kõiki teisi. Sellistes olukordades saate mähkida .grid
teises konteineris, nagu see:
kokkuvõte
Soovitan teil tungivalt katsetada ja leida lihtsam ja loomulikum lähenemine ülesannetele, mis tavaliselt on teatud keerukusastmega. Veebitehnoloogiad, nagu CSS, muutuvad üha võimsamaks ja karbist väljas olevaid lahendusi kasutades saate saavutada suurepäraseid tulemusi, ilma et peaksite oma koodi hooldama ja seda brauserimüüjatele loovutama.
Loodan, et teile meeldis see lühike õpetus ja see oli kasulik. Aitäh!
Autor valis välja Tech Käsitöö osana annetust saada Kirjutage annetuste eest programmi.