Crear animación basada en desplazamiento en vista completa()
CSS animation-timeline Propiedad aceptar view() La función, a su vez, devuelve una línea de tiempo que muestra cuántos elementos son visibles en la parte visible del contenedor de desplazamiento (formalmente llamado contenedor de desplazamiento). puerto rodante). En otras palabras, en lugar de que la animación siga una progresión lineal basada en el tiempo transcurrido, view() Ejecuta la animación según la visibilidad del elemento animado dentro del puerto de desplazamiento.
Me gusta equipararlo con la versión CSS de JavaScript. observador de intersección. Podemos ejecutar animaciones en el elemento cuando entra y sale del puerto de desplazamiento.
Aquí hay un ejemplo:
Bastante bonito, ¿verdad? de acuerdo a Dónde Las imágenes se encuentran en un carrusel desplazable, que cambia de pequeño y borroso en la distancia a más grande y claro a medida que llega al centro. tenemos un poco captura de desplazamiento Asegúrese de que todos los elementos de la imagen también estén detenidos allí.
¡No es difícil de hacer! Voy a mostrarte cómo en realidad es la misma animación antigua que estás acostumbrado a escribir en CSS, solo que se aplica a la línea de tiempo de la vista en lugar de a la línea de tiempo normal.
Pero primero, el diseño general.
Lo que estoy haciendo aquí es sólo un elemento al que llamo .carousel:
<main class="carousel">
<!-- scroll items -->
</main>
elementos en .carousel Establezca el diseño en una sola fila, que es una sola fila con un flexbox. También nos aseguraremos de que cualquier contenido que desborde su espacio sea desplazable:
.carousel {
display: flex;
width: max(480px, 50vw);
overflow-x: auto;
}
Por supuesto, necesitamos elementos dentro de él que se puedan desplazar. Una presentación de diapositivas de imágenes.
<main class="carousel">
<div class="carousel-slide">
<!-- (optional) empty bookend slide -->
</div>
<div class="carousel-slide">
<img src="https://css-tricks.com/creating-scroll-based-animations-in-full-view/image-1.jpeg" alt="alt text for image 1">
</div>
<div class="carousel-slide">
<img src="https://css-tricks.com/creating-scroll-based-animations-in-full-view/image-2.jpeg" alt="alt text for image 2">
</div>
<!-- etc -->
<div class="carousel-slide">
<!-- (optional) empty bookend slide -->
</div>
</main>
En cuanto al estilo de los elementos, cada uno tiene un tamaño de un tercio del espacio disponible para que veamos tres elementos a la vez al desplazarnos:
.carousel {
/* same as before */
.carousel-slide {
flex-shrink: 0;
width: calc(100% / 3); /* show three at a time */
aspect-ratio: .8;
img {
width: 100%;
}
}
}
luego desplácese
hemos establecido overflow-x En .carouselconvirtiéndolo oficialmente en nuestro contenedor rodante. Podemos agregar un pequeño ajuste de desplazamiento para asegurarnos de que solo nos desplazamos por un elemento a la vez.
.carousel {
/* same as before */
scroll-snap-type: x mandatory;
scroll-behavior: smooth; /* optional for smooth scrolling */
scrollbar-width: none; /* optional to hide the scrollbar */
}
Queremos asegurarnos de que la diapositiva se alinee con el centro del contenedor de desplazamiento cuando encaje en su lugar:
.carousel-slide {
/* etc. */
scroll-snap-align: center;
}
Esto es lo que tenemos hasta ahora:
Lo siguiente es la animación.
Esto es lo realmente interesante que mencioné al principio: las animaciones de la línea de tiempo de visualización son en realidad las mismas que cualquier otra animación CSS que escribas usando fotogramas clave. En este caso, queremos fotogramas clave donde los elementos del carrusel sean pequeños y borrosos al principio y al final, pero se vuelvan más grandes y claros en el medio de la animación.
@keyframes slide {
/* from start to 45%, and to the end (100%) */
45%, 100% {
transform: scale(0.5);
border-radius: 20px;
filter: blur(6px) brightness(.8);
}
/* middle */
50% {
transform: scale(1);
border-radius: 4px;
filter: none;
}
}
Parece familiar, ¿verdad? ¡Este es el tipo de CSS que has estado escribiendo! ¿Adivina qué? Animamos el elemento que queremos animar, tal como lo harías normalmente:
.carousel-slide {
/* etc. */
animation: slide;
}
La única diferencia es que queremos que la animación se ejecute en la línea de tiempo actual del elemento. view() en lugar de un horario regular. Eso es animation-timeline La propiedad entra en juego:
.carousel-slide {
/* etc. */
animation: slide;
animation-timeline: view(inline);
}
Ahora, Técnicamente Hablando de eso, podemos grabar directamente la línea de tiempo en animation Una propiedad abreviada como cualquier otra propiedad de composición de animación, por ejemplo, animation-name, animation-delay, animation-durationetc. Pero la asignación de funcionalidad de línea de tiempo de esta manera aún no es compatible con ningún navegador. Por tanto, tu mejor opción en estos momentos es autodeclararse. Por favor haz una declaración atrás este animation taquigrafía; de lo contrario, es posible que se encuentre sobrescribiendo sin darse cuenta la línea de tiempo de su vista. auto (valor de atributo predeterminado) en lugar de view().
Nuestra demostración está completa:
¿Viste eso? Todo lo que realmente hacemos es configurar una animación CSS que se ejecuta en el elemento. Sin embargo, en lugar de ejecutarse en la línea de tiempo predeterminada, la animación se ejecuta a medida que el elemento aparece y desaparece de la vista. Ésta es la diferencia entre la línea de tiempo estándar y la línea de tiempo de vista.
view() y scroll()
¡Pero espera! puede que lo sepas o no view() La línea de tiempo es parte de un conjunto de funciones más amplio llamado Animación basada en desplazamiento CSS. y view() No es la única característica compatible animation-timeline propiedad. todavía tenemos scroll() Función.
este scroll() La función crea un Línea de tiempo de progreso desplazable Esto está relacionado con la posición de desplazamiento del contenedor, mientras que view() Crear un Ver cronograma de progreso Esto se basa en la visibilidad del elemento dentro de su contenedor.
¡Ambas características tienen sus usos! generalmente pienso view() Mejor para exhibiciones de proyectos específicos. Por ejemplo, si queremos animar una diapositiva Solo cuando una diapositiva específica se desplaza al puerto de desplazamiento,Entonces view() La funcionalidad encaja perfectamente. Es por eso que me centré en ello en el ejemplo del carrusel: queremos rastrear la posición del elemento en el puerto de desplazamiento y ejecutar animaciones en consecuencia.
Insertar parámetros y animation-range
Quizás también te preguntes qué hay exactamente entre paréntesis. view() Función. Después de todo, es una función, por lo que tiene que aceptar algo en ella, ¿verdad?
CSS view() Hay dos parámetros: eje (block, inline, xy y)y ilustración. El parámetro de inserción define el desplazamiento desde el borde del puerto de desplazamiento dentro del cual se rastrea el elemento animado. La sintaxis oficial es la siguiente:
animation-timeline: view(<axis> <view-timeline-inset>);
…es sólo una forma elegante de saber específicamente qué área del puerto de desplazamiento queremos activar la animación. Para algunas animaciones, la línea de tiempo de inicio y finalización puede cortar el contenido cuando el elemento entra y sale completamente del puerto de desplazamiento.

¡Esto no es posible! Queremos que cada elemento se deslice completamente hacia adentro al ingresar por completo al puerto de desplazamiento, no al salir por completo. Es por eso que todos los proyectos parecen tan entrelazados: todos están en diferentes puntos de la línea de tiempo de la vista.
Aquí es donde el parámetro de inserción marca una gran diferencia. Podemos ser más específicos y decir que queremos que cada elemento inicie su animación cuando emerge de la parte inferior del puerto de desplazamiento.
animation: slide-in linear both;
animation-timeline: view(100% 0%);
Ah, mucho mejor:
este animation-range La propiedad funciona de manera similar.
animation-range: entry; /* same as: entry 0 entry 100%; */
este animation-range La propiedad acepta otras palabras clave, incluidas exit (cuando el elemento sale del puerto de desplazamiento), cover (cuando los elementos comienzan a entrar y salir del puerto de desplazamiento), y contain (cuando el elemento entra completamente y luego sale completamente del puerto de desplazamiento) y así sucesivamente. Geoff ha publicado una serie de notas y ejemplos. Mira cada uno específicamente.
Último ejemplo de carrusel
En términos generales, los carruseles utilizan efectos como desvanecimiento, zoom y paralaje. Sin embargo, dado que la mayoría de las propiedades CSS son animables, e incluso aquellas que no se pueden animar se pueden engañar usando propiedades CSS registradas (como en el caso de las líneas de degradado), puedes optar por explorar formas más creativas de usarlas. view() para carrusel.
A continuación se muestra un ejemplo en el que la animación de solo la posición del fondo crea un movimiento agradable en el carrusel.