Toate în perspectivă: Parallax CSS pur și alte efecte de defilare

Urmați împreună utilizând aceste Codepens:

Parallax de bază
Parallax cu obiect fix

În ciuda afirmațiilor că „paralaxa este moartă”, efectul este foarte viu și bine - și captivant - atunci când este pus în aplicare corect. Din păcate, de nouă ori din zece, implementarea este încorporată în Javascript. Jocul cu ascultătorii de evenimente de defilare reprezintă o activitate riscantă pentru performanță, iar modificarea DOM declanșează direct redări inutile, provocând animații chic și defilări lipicioase. Paralaxa corectă poate fi extrasă folosind JS. Iată un articol excelent despre cum trebuie făcut:

Dar pentru animații cu defilare mai simple, utilizarea CSS pur este o abordare performantă, neperformantă.

Setarea de bază

Ca prim exemplu, vom crea o pagină cu antet paralax și conținut de pagină statică. Deoarece scurgem Javascript, nu avem acces la poziția de derulare a ferestrei și nu avem nevoie de ea! Cheia pentru a elimina efectul este să profitați de perspectivă. Vom crea 2 straturi de conținut. Conținutul pe care dorim să-l defilăm mai lent, va fi plasat „mai departe” de utilizator pe axa z. Acest lucru va forța browserul să facă toate lucrările de ridicare grea pentru noi.

Iată marcajul de bază:

  
    

Titlu      
    

Conținutul site-ului

  

Să eliminăm CSS. Trebuie să spunem browserului să profite de perspectiva de-a lungul axei Z. Facem acest lucru adăugând proprietatea perspectivă la clasa noastră de înveliș:

perspectivă: 1px;

O valoare mai mare în perspectivă va determina o diferență mai mare de viteze de defilare între straturi.

În continuare, forțăm învelișul să preia 100% din portofoliul browserului și să setăm overflow-ul la auto. Aceasta permite conținutului ambalajului să deruleze ca de obicei, dar viteza de derulare pentru descendenți va fi în raport cu valoarea de perspectivă a învelitorului:

.wrapper {
  inaltime: 100vh;
  overflow-x: ascuns;
  overflow-y: auto;
  perspectivă: 1px;
}

Prima div va conține conținutul antetului nostru. Imaginea de fundal, aplicată unui pseudo element, va fi amplasată cu un pixel „departe” de utilizator pe axa z, în timp ce conținutul va fi nivelat cu restul paginii și va defila la viteza normală.

Nimic prea special nu se întâmplă în clasa .section aplicată antetului. Definește înălțimea și formatează conținutul. Iată CSS:

.secțiune {
  inaltime: 100vh;
  afișare: flex;
  align-items: centru;
  justifica-continut: centru;
  font-size: 48px;
  culoare albă;
}

Toată bunătatea paralaxului se întâmplă în pseudo-element:

.parallax :: după {
  continut: "";
  poziție: absolută;
  top: 0;
  dreapta: 0;
  partea de jos: 0;
  stanga: 0;
  transform: scală translateZ (-1px) (2);
  fundal: 100%;
  index z: -1;
  fundal-imagine: url (unele link-uri la o imagine);
}

Pseudo elementul este plasat în spatele conținutului antetului. translateZ (-1px) definește distanța stratului față de utilizator de-a lungul axei Z.

Deoarece mutăm stratul mai departe înapoi, conținutul pare mai mic (gândiți-vă la ce se întâmplă când mutați un obiect de la dvs.). Pentru a ține cont de acest lucru, trebuie să scalăm stratul înapoi la dimensiuni, folosind scala (2).

Dacă perspectiva este setată la 1px, formula pentru a scala straturile înapoi la dimensiunea lor implicită este: 1 + (translateZ * -1) / perspectivă.

În cazul nostru, o traducereZ (-2px) ar necesita o scară (3) și așa mai departe ...

Adăugați ceva conținut static sub antet și veți avea un efect de paralax frumos, fără a fi nevoie de JS!

Iată un link către Codepen pentru acest exemplu.

Acum pentru partea distractivă: Parallax cu obiect fix

Paralaxia de bază este excelentă. Acesta respiră viața într-o altă pagină web statică. Dar puteți face mult mai mult cu perspectiva în CSS. Acest lucru a devenit clar pentru a lucra la o animație de defilare pentru site-ul meu de portofoliu.

Am vrut ca o grămadă de cărămizi SVG lego să se despartă cu viteze diferite, în timp ce utilizatorul defila pe pagina mea de pornire. După ce am convins cu JS o vreme, mi-am dat seama că acest efect poate fi obținut cu CSS pur - și să fii buturiu la fel!

Ideea este de a crea straturi separate de obiecte în containerul principal, fiecare cu o valoare diferită de translateZ (citire: viteză de defilare). În timp ce implementam acest lucru, mi-am dat seama că, în traducerea și scalarea obiectelor, nu aveam nicio modalitate de a urmări pozițiile lor x și y (acestea se vor schimba în raport cu valoarea de traducere a obiectului). Pentru a rezolva acest lucru, am înfășurat fiecare obiect într-un container clar care se potrivește întregului ecran. Aș putea apoi să poziționez obiectul exact în înveliș și să aplic transluzul și scara pe învelitor în loc de obiectul însuși.

Este necesară o singură clasă .wrapper pentru a defini mărimea tuturor obiectelor:

.object-wrapper {
  poziție: absolută;
  top: 0;
  dreapta: 0;
  partea de jos: 0;
  stanga: 0;
  fundal: niciuna;
  justifica-continut: centru;
}

Vitezele diferite pot fi apoi definite și aplicate la ambalajele de obiect:

.speed-1 {
  transform: scală translateZ (-1px) (2);
}
.speed-2 {
  transform: scară translateZ (-2px) (3);
}
.speed-3 {
  transform: scară translateZ (-3px) (4);
}

Iată un Codepen care demonstrează Parallaxul cu obiect fix:

Pure CSS oferă o lume de posibilități de animare a conținutului în raport cu poziția de defilare - iar cea mai bună parte este că, în cazul scăderii JS, este aproape imposibil să încurci performanțele!

Când vine vorba de paralaxe performante, este vorba într-adevăr despre perspectivă.