CSS tehnike za učinek materiala

Vodnik o različnih tehnikah za učinek ripplea s pomočjo CSS in JavaScript

Pred kratkim sem moral v spletno aplikacijo implementirati valoviti učinek iz materiala. In potem sem ugotovil, da nimam pojma, kako se to izvaja. To me je vodilo v pot, da sem preučeval obstoječe izvedbe in celo predstavil popolnoma novo tehniko, ki bi vam bila lahko koristna.

Kakšen je ta učinek valovanja?

Počakajte, da ne poznate nihajnega učinka Googlovega materiala Design? Že vrsto let živite v jami?

Učinek valovanja se uporablja, ko pritisnete gumb. Enako deluje tudi z interakcijo z miško ali dotikom.

Položaj, ki ga kliknete ali se dotaknete gumba, se imenuje kontaktna točka. Od tam naprej se valijoča ​​premakne navzven in izgubi motnost, ko se poveča, dokler ne napolni celotnega gumba. Potem popolnoma izgine.

Dinamika tega učinka valovanja je podobna valovanjem, ki jih dobite, ko se dotaknete tekoče površine ali ko spustite skalo v jezero.

Valovi, ki jih boste našli na spletu

Po opravljenih raziskavah sem lahko našel dve glavni tehniki, ki se uporabljata za izvajanje učinka ripple na spletnih aplikacijah.

Uporaba :: po psevdoelementu

S to tehniko je psevdo element :: after, oblikovan kot polprozoren krog in animiran, da raste in bledi. Gumb vsebnika mora imeti preliv: skrit, tako da krog nikoli ne preplavi zunaj površine gumba in položaj: relativno, da je krog enostavno postaviti v gumb. Več podrobnosti o tej tehniki si lahko preberete v tem članku Ionuț Colceriu.

Ena od odličnih stvari v tej tehniki je, da gre za čisto rešitev CSS za učinek ripple. Vendar se učinek valovanja vedno začne od središča gumba, namesto točke stika. To niso najbolj naravne povratne informacije.

Lahko bi ga izboljšali z uporabo JavaScript za shranjevanje kontaktne točke in ga uporabili za postavitev valovanja. Točno to je material.io storil za svojo komponento spletnega valovanja. Uporablja spremenljivke CSS za shranjevanje točke stika in :: pseudo-element uporablja te spremenljivke za pozicioniranje.

Uporaba otroških elementov

V bistvu ta tehnika uporablja isto strategijo kot prej. Toda namesto psevdoelementa v notranjosti gumba doda span element, ki ga je nato mogoče postaviti skozi JavaScript. To tehniko je v tem članku opisal Jhey Tompkins.

Najenostavnejša izvedba ustvari razpon za vsak klik gumba in s položajem miške na dogodku klika spremeni položaj razpona. S pomočjo CSS animacije razpon raste in bledi, dokler ne postane popolnoma pregleden. Lahko se odločimo, da bomo razpon odstranili iz DOM-a, ko se animacija konča, ali pa ga pustimo tam pod preprogo - nihče res ne bo opazil prozornega razpona, ki visi okoli.

Našel sem drugo različico tega, pri katerem je podrejeni element svg namesto razpona in svg je animiran s pomočjo JavaScript. To različico razloži Dennis Gaebel, v bistvu pa se zdi, da je enako in morda omogoča uporabo kompleksnih oblik in učinkov SVG.

Težava pri oddaji vnosov

Obe zgoraj opisani tehniki se zdita odlični. To se zgodi, ko sem jih poskusil uporabiti pri vhodnih elementih z type = submit:

Zakaj ne delajo?

Vhodni element je zamenjani element. Skratka, to pomeni, da s temi elementi lahko storite zelo malo, kar zadeva DOM in CSS. Natančneje, ne morejo imeti podrejenih elementov in tudi psevdoelementov. Zdaj je jasno, zakaj te tehnike ne uspejo.

Če torej uporabljate Material Design, je bolje, da se izognete vnosu [type = submit] in se držite elementov gumbov. Ali pa samo še naprej branje.

Dodajanje valov za oddajo vložkov

V spletni aplikaciji, ki sem jo delal, smo že imeli veliko gumbov za oddajo. Če bi jih vsi spremenili v drugačen element, bi bilo potrebno veliko dela in veliko tveganje, da bi zlomili tabele slogov in logiko JavaScript. Zato sem moral ugotoviti, kako dodati valovanja obstoječim gumbom za oddajo.

Uporaba embalažne posode

Hitro sem spoznal, da lahko gumb za pošiljanje zavijem v element vdelanega bloka in uporabim element vgrajenega bloka kot površino valovanja. Tu je kratki predstavitveni prikaz:

Čeprav mi je ta rešitev všeč zaradi njene enostavnosti, je vseeno zahtevalo, da oznako spremenim na preveč mestih. In vedela sem, da bo to krhka rešitev - novi razvijalci bodo vstopili v projekt in ustvarili gumbe za oddajo, ne da bi jih pravilno zavili v valovito površino. Tako sem še naprej iskal druge rešitve, za katere ni bilo treba spremeniti DOM-a.

Radialni gradienti

Sintaksa radialnega gradienta mi omogoča nadzor nad središčem in velikostjo gradienta. Seveda mi omogoča tudi nadzor barve naklona, ​​vključno s polprosojnimi barvami. In nikoli ne preplavi elementa, na katerega se nanaša. Tako se zdi, kot da že počne vse, kar potrebujem!

Ni tako hitro ... manjka samo ena stvar: lastnost slike v ozadju ni animirana. Z uporabo CSS animacij nisem mogel doseči, da bi gradient naraščal in zbledel do preglednega. Uspelo mi je, da je zrasel z animiranjem lastnosti velikosti ozadja, vendar je bilo to vse, kar sem lahko naredil.

Poskusil sem še nekaj drugih stvari, na primer, da sem kot animirano sliko (z uporabo apng formata) zbledeli krog uporabil kot ozadje. Potem pa nisem mogel nadzirati, kdaj se je zanka slike začela in končala.

Končno rešitev z JavaScript

Česa ne morete storiti v CSS, lahko to storite tudi v JavaScript. Potem ko sem porabil več časa, kot sem si želel priznati, da poskušam doseči ta učinek pri uporabi CSS animacij, sem samo obupal in se odločil, da bom animacijo napisal v JavaScript.

Začela sem z zgoraj raztopino radialnega gradienta in uporabila window.requestAnimationFrame za izdelavo tekoče animacije radialnega gradienta, ki raste in bledi. Tu je moja končna rešitev:

Zaključek

Na gumbe za oddajo je mogoče imeti valovite učinke, samo ne pri CSS.

Nisem mogel najti te tehnike dokumentirane nikjer na spletu, zato jo poimenujem svojo. Leonardova tehnika vakovanja ne zahteva sprememb DOM-a in deluje za kateri koli element, ker se ne zanaša na psevdoele ali podrejene elemente. Vendar to ni brezhibna rešitev.

Prvič, obstaja uspešnost. Z animiranjem gradienta z JavaScriptom izgubite veliko optimizacij brskalnika. Ker pa je edina lastnost, ki se spreminja, ozadje slike, sumim, da se brskalnikom ne bi bilo treba znova nalagati in bi le zahteval ponovno uporabo slogov in preoblikovanje elementa. V praksi se zgodi prav to in uspešnost je res dobra. Izjema od te izjave je Firefox Mobile, ki iz nekega razloga ne sledi korak z animacijo. (uredi: animacija je gladka v sodobnih različicah Firefox Mobile)

Drugič, tehnika uporablja lastnost gumba v ozadju. Če vaš dizajn zahteva, da se na vaših gumbih na ozadju nanaša slika, bi učinek ripple to premagal. Če to sliko resnično potrebujete v svojem dizajnu, potem lahko JavaScript spremenite tako, da nariše radialni gradient na vrh obstoječe slike ozadja.

Tretjič, to ne deluje v Internet Explorerju. Vendar ne vidim nobenega razloga, da ne bi deloval z IE10 in novejšimi. Mogoče zato, ker IE uporablja drugačno skladnjo za radialni-gradient. Toda koga danes zanima IE? (uredi: ta metoda deluje brez težav v Internet Explorerju 11)