Tutto in prospettiva: parallasse CSS puro e altri effetti di scorrimento

Seguire usando questi codici:

Parallax di base
Parallasse ad oggetti fissi

Nonostante affermi che "la parallasse è morta", l'effetto è molto vivo e vegeto - e accattivante - se implementato correttamente. Sfortunatamente, nove volte su dieci, l'implementazione è fallita in Javascript. Giocare con i listener di eventi di scorrimento è un'attività rischiosa per le prestazioni e la modifica del DOM avvia direttamente rendering non necessari, causando animazioni instabili e scroll appiccicosi. La parallasse corretta può essere estratta usando JS. Ecco un eccellente articolo su come dovrebbe essere fatto:

Ma per animazioni a scorrimento più semplici, l'uso di CSS puro è un approccio infallibile e performante.

L'installazione di base

Come primo esempio, creeremo una pagina con un'intestazione di parallasse e un contenuto di pagina statico. Poiché stiamo abbandonando Javascript, non abbiamo accesso alla posizione di scorrimento della finestra e non ne abbiamo bisogno! La chiave per ottenere l'effetto è di sfruttare la prospettiva. Creeremo 2 livelli di contenuto. Il contenuto che vogliamo scorrere più lentamente verrà posizionato "più lontano" dall'utente sull'asse z. Questo costringerà il browser a fare tutto il lavoro pesante per noi.

Ecco il markup di base:

  
    

Titolo      
    

Contenuto del sito

  

Cerchiamo di arricchire il CSS. Dobbiamo dire al browser di sfruttare la prospettiva lungo l'asse z. Lo facciamo aggiungendo la proprietà prospettiva alla nostra classe wrapper:

prospettiva: 1px;

Un valore di prospettiva più grande causerà una maggiore differenza nelle velocità di scorrimento tra i livelli.

Successivamente, forziamo il wrapper a occupare il 100% del viewport del browser e impostare overflow-y su auto. Ciò consente al contenuto all'interno del wrapper di scorrere normalmente, ma la velocità di scorrimento per i discendenti sarà ora relativa al valore prospettico del wrapper:

.wrapper {
  altezza: 100 vh;
  overflow-x: nascosto;
  overflow-y: auto;
  prospettiva: 1px;
}

Il primo div conterrà il nostro contenuto di intestazione. L'immagine di sfondo, applicata a uno pseudo elemento, verrà posizionata di un pixel "lontano" dall'utente sull'asse z, mentre il contenuto sarà a livello con il resto della pagina e scorrerà alla velocità normale.

Non succede nulla di troppo speciale nella classe .section applicata all'intestazione. Definisce l'altezza e formatta il contenuto. Ecco il CSS:

.sezione {
  altezza: 100 vh;
  display: flessibile;
  align-items: center;
  giustificare-contenuto: centro;
  dimensione carattere: 48px;
  colore bianco;
}

Tutta la bontà della parallasse si verifica nello pseudo elemento:

.parallax :: after {
  contenuto: "";
  posizione: assoluta;
  in alto: 0;
  a destra: 0;
  in basso: 0;
  sinistra: 0;
  trasformare: translateZ (-1px) scale (2);
  dimensione dello sfondo: 100%;
  indice z: -1;
  immagine di sfondo: url (alcuni collegamenti ad alcune immagini);
}

Lo pseudo elemento è posizionato dietro il contenuto dell'intestazione. translateZ (-1px) definisce la distanza del livello dall'utente lungo l'asse z.

Poiché stiamo spostando il livello più indietro, i contenuti appaiono più piccoli (pensa a cosa succede quando sposti un oggetto lontano da te). Per tenere conto di ciò, dobbiamo ridimensionare il livello alla dimensione, usando scale (2).

Se la prospettiva è impostata su 1px, la formula per ridimensionare i livelli alla loro dimensione predefinita è: 1 + (translateZ * -1) / prospettiva.

Nel nostro caso, una translateZ (-2px) richiederebbe una scala (3) e così via ...

Aggiungi del contenuto statico sotto l'intestazione e otterrai un bellissimo effetto di parallasse senza bisogno di JS!

Ecco un link al Codepen per questo esempio.

Ora per la parte divertente: parallasse a oggetti fissi

La parallasse di base è fantastica. Dà vita a una pagina web altrimenti statica. Ma puoi fare molto di più con la prospettiva nei CSS. Questo mi è diventato chiaro lavorando a un'animazione di scorrimento per il mio sito portfolio.

Volevo che una pila di mattoncini Lego SVG si spezzasse a velocità diverse mentre l'utente scorreva la mia homepage. Dopo aver armeggiato un po 'con JS per un po', mi sono reso conto che questo effetto poteva essere ottenuto con CSS puro - ed essere burroso!

L'idea è quella di creare strati separati di oggetti all'interno del contenitore principale, ognuno con un diverso valore translateZ (leggi: velocità di scorrimento). Durante l'implementazione, ho capito rapidamente che nella traduzione e nel ridimensionamento degli oggetti, non avevo modo di tenere traccia delle loro posizioni xey (sarebbero cambiate rispetto al valore translZ dell'oggetto). Per risolvere questo, ho avvolto ogni oggetto in un contenitore trasparente che si adatta all'intero schermo. Potrei quindi posizionare l'oggetto con precisione all'interno del wrapper e applicare translateZ e ridimensionarlo al wrapper anziché all'oggetto stesso.

È necessaria solo una classe .wrapper per definire la dimensione per tutti gli oggetti:

.object-wrapper {
  posizione: assoluta;
  in alto: 0;
  a destra: 0;
  in basso: 0;
  sinistra: 0;
  sfondo: nessuno;
  giustificare-contenuto: centro;
}

È quindi possibile definire e applicare velocità diverse ai wrapper di oggetti:

.speed-1 {
  trasformare: translateZ (-1px) scale (2);
}
.speed-2 {
  trasforma: scala translateZ (-2px) (3);
}
.speed-3 {
  trasforma: scala translateZ (-3px) (4);
}

Ecco un Codepen che dimostra la parallasse degli oggetti fissi:

Pure CSS offre un mondo di possibilità per animare i contenuti in relazione alla posizione di scorrimento - e la parte migliore è che, abbandonando JS, è quasi impossibile rovinare le prestazioni!

Quando si tratta di parallasse performante, si tratta davvero di prospettiva.