Skip links

Traer el paralaje a través de la animación CSS impulsada por el desplazamiento

Durante la década de 2010 Paralaje Es la forma garantizada de hacer que su sitio web sea «genial». De hecho, Chris Coyier es Escrito ya en 2008.

Para aquellos que no están familiarizados con el concepto, Parallax es un patrón en el que diferentes elementos de una página web se mueven a diferentes velocidades a medida que el usuario se desplaza, creando un aspecto tridimensional y en capas. El verdadero efecto de paralaje alguna vez solo fue posible usando JavaScript. Sin embargo, Animación impulsada por desplazamiento Ahora nos han dado una solución solo CSS que no está bloqueada por la línea principal que puede afectar a las animaciones de JavaScript.

El paralaje ya puede ser un poco cliché, pero creo que esta nueva función CSS vale la pena una reexaminación.

Notas: Las animaciones impulsadas por desplazamiento se encuentran en Chrome, Edge, Opera y Firefox (detrás de las banderas de características) cuando se escriben. Al seguir este tutorial, use un navegador compatible.

Código de inicio

En este ejemplo, aplicaremos la animación de paralaje al fondo y los íconos en las tres secciones de «héroes» de una página web con temática cósmica. Comenzaremos con algunos ligeros marcados que contienen héroes alternativos y piezas de texto, junto con algunas tonterías relacionadas con el espacio como contenido de marcador de posición.

Agregar animación inicial

Agreguemos animaciones al modo de fondo en cada sección de héroe para modificar la posición de fondo.

@keyframes parallax {
  from {
    background-position: bottom 0px center;
  }
  to {
    background-position: bottom -400px center;
  }
}

section.hero {
  /* previous code */
+ animation: parallax 3s linear;
}

Aquí usamos keyframes Las reglas de CSS crean posiciones de inicio y finalización para el fondo. Luego usamos esta animación para adjuntar esta animación a cada una de nuestras secciones de héroes. animation propiedad.

Por defecto, las animaciones CSS se basan en la duración y se ejecutan cuando el selector especificado se carga en el DOM. Si actualiza el navegador, verá que la animación se ejecuta durante tres segundos inmediatamente después de que se carga la página.

https://www.youtube.com/watch?v=26dv5mgw10k

No queremos que nuestra animación se active de inmediato. En cambio, tenemos la intención de usar la posición de desplazamiento de la página como referencia para calcular el progreso de la animación.

La animación dirigida por carrete ofrece dos nuevos Horario de animación Función CSS. Estas adiciones, view() y scroll()Al calcular el progreso de la animación CSS, dígale al navegador a qué referirse. Usaremos view() Características más tarde, pero por ahora, centrémonos en scroll(). este Programa de progreso de desplazamiento Combina el proceso de la animación con la posición de desplazamiento del usuario en el contenedor de desplazamiento. Los parámetros se pueden incluir para cambiar el eje de desplazamiento y los elementos del contenedor, pero no son necesarios para nuestra implementación.

Usemos el cronograma de progreso del carrete a la animación:

section.hero {
  /* previous code */
- animation: parallax 3s linear;
+ animation: parallax linear;
+ animation-timeline: scroll(); 
}

Si actualiza la página, notará que la posición de fondo de cada sección de héroes también cambiará al desplazarse hacia abajo. Si se desplaza, la animación se invertirá. Como beneficio adicional, esta animación CSS se procesa desde el hilo principal y, por lo tanto, no está bloqueada por ningún posible JavaScript.

https://www.youtube.com/watch?v=lhjgxmvi96i

Usando el cronograma de progreso de la vista

Ahora agregemos una nueva capa de paralaje animar el texto y los íconos del título en cada sección de héroes. De esta manera, el modo de fondo, el título y el contenido de la página de inicio parecen desplazarse a diferentes velocidades. Usaremos scroll() La función CSS también se usa aquí para horarios de animación.

@keyframes float {
  from {
    top: 25%;
  }
  to {
    top: 50%;
  }
}

.hero-content {
  /* previous code */
+ position: absolute;
+ top: 25%;
+ animation: float linear;
+ animation-timeline: scroll(); 
}

https://www.youtube.com/watch?v=hhb0ytmmj5m

Eso no es muy correcto. Las animaciones de las secciones en la parte inferior de la página casi se realizan cuando entran. Afortunadamente, el programa de animación View resuelve este problema. Al establecer animation-timeline La propiedad es view()Nuestra animación se basa en la posición del cuerpo en el puerto de olas de desplazamiento, que es parte del contenedor visible al desplazarse. Al igual que el desplazamiento de la línea de tiempo animado, el desplazamiento inverso también revertirá la animación.

Intentemos cambiar las propiedades del horario de animación del texto del héroe:

.hero-content {
  /* previous code */
- animation-timeline: scroll(); 
+ animation-timeline: view(); 
}

Se ve bastante bien, pero hay un problema con el contenido del título que fluye en la vista al desplazar el documento. Esto se debe a que la línea de tiempo de vista se calcula en función del posicionamiento de animación original de los elementos del tema.

https://www.youtube.com/watch?v=lclra2ey0_a

Podemos agregar un inset Parámetros view() Función. Esto puede ajustar el tamaño del contenedor donde ocurre la animación. de acuerdo a Documentación de MDN«La ilustración se usa para determinar si un elemento determina la longitud del programa de animación en la vista. En otras palabras, la animación continuará mientras el elemento esté en la vista ilustrada ajustada».

Entonces, al usar valores negativos, hacemos que el contenedor sea más grande que la ventana más grande y activar la animación para comenzar antes y terminar un poco después de que el sujeto sea visible. Esto ilustra el hecho de que el tema se mueve durante la animación.

- animation-timeline: view();
+ animation-timeline: view(-100px);

Ahora tanto el texto como el fondo son animados sin problemas a diferentes velocidades.

Ajustar animaciones usando el rango de animación

Hasta ahora, todos hemos contratado voluta y vista Programa de progreso. Veamos otra forma de ajustar la hora de inicio y finalización de la animación animation-range propiedad. Se puede utilizar para modificar la posición de la línea de tiempo de la animación donde se iniciará y terminará el horario a lo largo de la línea de tiempo.

Añadiremos view() Animación de la línea de tiempo para #spaceship Emoji:

@keyframes launch {
  from {
    transform: translate(-100px, 200px);
  }
  to {
    transform: translate(100px, -100px);
  }
}

#spaceship {
  animation: launch;
  animation-timeline: view();
}

De nuevo, vemos que el emoji regresa a él 0% Posición una vez que su posición unificada original está fuera del puerto de desplazamiento.

https://www.youtube.com/watch?v=W1YBHVWXFX0

Como se mencionó anteriormente, la animación se basa en la posición original de acción previa del tema. Anteriormente, agregamos los parámetros de ilustración a view() Función. También podemos ajustar el rango de animación y decirle a nuestra animación que continúe superando el 100% del horario de animación sin tener que manipular las ilustraciones del horario de vista en sí.

#spaceship {
  animation: launch;
  animation-timeline: view();
+ animation-range: 0% 120%;
}

Ahora la animación continúa hasta que desplazamos el 20% del desplazamiento adicional fuera de la línea de tiempo de desplazamiento calculado.

https://www.youtube.com/watch?v=zzpy8xhafay

Supongamos que queremos #comet emoji, pero no queremos que comience a animar hasta que pase 4rem Desde la parte inferior del puerto de desplazamiento:

@keyframes rotate {
  from {
    transform: rotate(0deg) translateX(100px);
  }
  to {
    transform: rotate(-70deg) translateX(0px);
  }
}

#comet {
  animation: rotate linear;
  transform-origin: center 125px;
  animation-timeline: view();
  animation-range: 4rem 120%;
}

Aquí vemos la animación de «Retraso»:

https://www.youtube.com/watch?v=wzncii4xepu

¡También podemos combinar rangos de animación para ejecutar animaciones completamente diferentes en diferentes puntos en la misma línea de tiempo! Vamos a ilustrar esto combinando rangos de animación #satellite Íconos en la parte superior de la página. El resultado es que la primera animación es hasta que el ícono excede el 80% del carril de desplazamiento, y la segunda animación se hace cargo del último 20%.

@keyframes orbit-in {
  0% {
    transform: rotate(200deg);
  }
  100% {
    transform: rotate(0deg);
  }
}

@keyframes orbit-out {
  0% {
    transform: translate(0px, 0px);
  }
  100% {
    transform: translate(-50px, -15px);
  }
}

#satellite {
  animation: orbit-in linear, orbit-out ease;
  animation-timeline: view();
  animation-range: 0% 80%, 80% 110%;
}

https://www.youtube.com/watch?v=gnyjhjdxnwo

Copia de seguridad y accesibilidad

Nuestras páginas web contienen muchos elementos móviles que pueden causar incomodidad a algunos usuarios. Consideremos la accesibilidad a la sensibilidad del movimiento y combinemos prefers-reduced-motion Características de CSS Media.

Hay dos valores posibles: no-preferencey reduce. Si queremos ajustar la página web de forma predeterminada con animación y luego mejorar cada selector con animación y estilos relacionados, entonces podemos usar no-preference Habilitarlos.

@media (prefers-reduced-motion: no-preference) {
  .my-selector {
    position: relative;
    top: 25%;
    animation: cool-animation linear;
    animation-timeline: scroll(); 
  }
}

Sin embargo, para nosotros, si deshabilitamos todas las animaciones al mismo tiempo, el contenido web y la imagen aún se pueden ver. Esto se puede usar de manera concisa reduce Opciones. Es importante tener en cuenta que este enfoque de anulación es adecuado para nuestra situación, pero siempre debe considerar el impacto en un usuario en particular al implementar funciones de accesibilidad.

@media (prefers-reduced-motion: reduce) {
  .my-selector {
    animation: none !important;
  }
}

Además de considerar la accesibilidad, también debemos considerar que todos los navegadores no admiten animaciones impulsadas por desplazamiento al momento de escribir. Si nos importa mucho el usuario que vee la animación, podemos agregar un relleno múltiple (Enlace directo) Extienda esta función a los navegadores que actualmente no son compatibles. Sin embargo, esto obligará a la animación a ejecutarse en el hilo principal.

Además, podemos decidir que el rendimiento es suficiente para omitir animaciones en navegadores no compatibles, manteniendo así el hilo principal claro. En este caso podemos usar @supports Selector, incluidos estilos solo en navegadores compatibles.

Aquí está el código final para todo, incluido el retroceso de movimiento múltiple y reducido:

en conclusión

Fuimos, acabamos de recrear los efectos web clásicos utilizando animación dirigida por carrete voluta y vista Programa de progreso. También discutimos algunos parámetros que se pueden usar para ajustar el comportamiento de animación. Ya sea que paralaje sea su negocio, me gusta la idea de que podemos usar métodos modernos que podemos hacer antes … solo puede ser mejor mediante la mejora gradual de la mejora progresiva.

Más información

Leave a comment

Home
Account
Cart
Search
¡Hola! ¡Pregúntame lo que quieras!
Explore
Drag