Todo en perspectiva: Parallax CSS puro y otros efectos de desplazamiento

Siga junto con estos Codepens:

Paralaje Básico
Paralaje de objetos fijos

A pesar de las afirmaciones de que "la paralaje está muerta", el efecto está muy vivo y bien, y cautivador, cuando se implementa correctamente. Desafortunadamente, nueve de cada diez veces, la implementación está estropeada en Javascript. Jugar con oyentes de eventos de desplazamiento es un negocio arriesgado para el rendimiento, y la modificación del DOM desencadena directamente reproducciones innecesarias, lo que provoca animaciones entrecortadas y rollos adhesivos. Paralaje adecuado se puede sacar con JS. Aquí hay un excelente artículo sobre cómo debe hacerse:

Pero para animaciones de desplazamiento más simples, usar CSS puro es un enfoque infalible y eficaz.

La configuración básica

Como primer ejemplo, crearemos una página con un encabezado de paralaje y contenido de página estático. Debido a que estamos abandonando Javascript, no tenemos acceso a la posición de desplazamiento de la ventana, ¡y no lo necesitamos! La clave para lograr el efecto es aprovechar la perspectiva. Crearemos 2 capas de contenido. El contenido que queremos desplazar más lentamente, se colocará "más lejos" del usuario en el eje z. Esto obligará al navegador a hacer todo el trabajo pesado por nosotros.

Aquí está el marcado básico:

  
    

Encabezado

  
  
    

Contenido del sitio

  

Vamos a desarrollar el CSS. Necesitamos decirle al navegador que aproveche la perspectiva a lo largo del eje z. Hacemos esto agregando la propiedad de perspectiva a nuestra clase de contenedor:

perspectiva: 1px;

Un valor de perspectiva mayor causará una mayor diferencia en las velocidades de desplazamiento entre las capas.

A continuación, forzamos al contenedor a ocupar el 100% de la ventana gráfica del navegador y configuramos overflow-y en auto. Esto permite que el contenido dentro del contenedor se desplace como de costumbre, pero la velocidad de desplazamiento para los descendientes ahora será relativa al valor de perspectiva del contenedor:

.wrapper {
  altura: 100vh;
  overflow-x: oculto;
  desbordamiento-y: auto;
  perspectiva: 1px;
}

El primer div contendrá nuestro contenido de encabezado. La imagen de fondo, aplicada a un pseudo elemento, se colocará a un píxel "lejos" del usuario en el eje z, mientras que el contenido estará nivelado con el resto de la página y se desplazará a la velocidad normal.

No sucede nada especial en la clase .section aplicada al encabezado. Define la altura y formatea el contenido. Aquí está el CSS:

.sección {
  altura: 100vh;
  pantalla: flex;
  alinear elementos: centro;
  justify-content: centro;
  tamaño de fuente: 48 px;
  color blanco;
}

Toda la bondad de paralaje ocurre en el pseudo elemento:

.parallax :: after {
  contenido: " ";
  posición: absoluta;
  arriba: 0;
  derecha: 0;
  abajo: 0;
  izquierda: 0;
  transformar: traducirZ (-1px) escala (2);
  tamaño de fondo: 100%;
  índice z: -1;
  background-image: url (algún enlace a alguna imagen);
}

El pseudo elemento se coloca detrás del contenido del encabezado. translateZ (-1px) define la distancia de la capa del usuario a lo largo del eje z.

Debido a que estamos moviendo la capa más atrás, el contenido parece más pequeño (piense en lo que sucede cuando aleja un objeto de usted). Para dar cuenta de esto, debemos volver a escalar la capa al tamaño, usando scale (2).

Si su perspectiva se establece en 1px, la fórmula para volver a escalar las capas a su tamaño predeterminado es: 1 + (translateZ * -1) / perspective.

En nuestro caso, un translateZ (-2px) requeriría una escala (3) y así sucesivamente ...

¡Agregue contenido estático debajo del encabezado y obtendrá un hermoso efecto de paralaje sin necesidad de JS!

Aquí hay un enlace al Codepen para este ejemplo.

Ahora para la parte divertida: paralaje de objetos fijos

Paralaje básico es genial. Respira vida en una página web que de otro modo sería estática. Pero puedes hacer mucho más con la perspectiva en CSS. Esto me quedó claro al trabajar en una animación de desplazamiento para mi sitio de cartera.

Quería que una pila de ladrillos de lego SVG se separara a diferentes velocidades a medida que el usuario se desplazaba hacia abajo en mi página de inicio. Después de jugar un poco con JS por un tiempo, me di cuenta de que este efecto podría lograrse con CSS puro, ¡y ser muy suave!

La idea es crear capas separadas de objetos dentro del contenedor maestro, cada uno con un valor de traducción Z diferente (lectura: velocidad de desplazamiento). Al implementar esto, rápidamente me di cuenta de que al traducir y escalar los objetos, no tenía forma de hacer un seguimiento de sus posiciones x e y (cambiarían en relación con el valor de traslación del objeto). Para resolver esto, envolví cada objeto en un contenedor transparente que se ajustaba a toda la pantalla. Entonces podría colocar el objeto con precisión dentro del contenedor y aplicar el translateZ y la escala al contenedor en lugar del objeto en sí.

Solo se necesita una clase .wrapper para definir el tamaño de todos los objetos:

.object-wrapper {
  posición: absoluta;
  arriba: 0;
  derecha: 0;
  abajo: 0;
  izquierda: 0;
  fondo: ninguno;
  justify-content: centro;
}

Se pueden definir y aplicar diferentes velocidades a los envoltorios de objetos:

.speed-1 {
  transformar: traducirZ (-1px) escala (2);
}
.speed-2 {
  transformar: traducirZ (-2px) escala (3);
}
.speed-3 {
  transformar: traducirZ (-3px) escala (4);
}

Aquí hay un Codepen que demuestra Parallax de objetos fijos:

Pure CSS ofrece un mundo de posibilidades para animar contenido en relación con la posición de desplazamiento, y la mejor parte es que, al deshacerse de JS, ¡es casi imposible arruinar el rendimiento!

Cuando se trata de paralaje performante, realmente se trata de perspectiva.