Consigna y casos de uso
El objetivo es vincular el progreso de la animación al desplazamiento sin ejecutar un manejador de JavaScript en cada evento de scroll. Las animaciones controladas por desplazamiento de CSS exponen líneas de tiempo de progreso de scroll y de progreso de vista a través de animation-timeline, scroll() y view(). La implementación aún necesita una alternativa de respaldo (fallback), comportamiento para movimiento reducido, decisiones de contención y una política clara de compatibilidad con navegadores.
Qué evalúa el entrevistador
- Si distingues el progreso de un contenedor con scroll del progreso de visibilidad de un elemento.
- Si colocas la declaración
animation-timelinedespués de la propiedad abreviadaanimation. - Si eliges transform y opacity antes que propiedades que desencadenan el recálculo del diseño (layout).
- Si proporcionas una consulta de características (feature query) o una línea base no animada.
- Si respetas
prefers-reduced-motiony preservas el contenido legible sin movimiento. - Si mides páginas largas, contenedores con scroll anidados, elementos sticky y el rendimiento en dispositivos móviles.
Aclaraciones antes de responder
- ¿El progreso está vinculado a la página, a un contenedor con scroll anidado o a un elemento que entra en el viewport?
- ¿La animación debe comunicar un estado o es meramente decorativa?
- ¿Qué navegadores y webviews integradas están dentro del alcance?
- ¿Qué deben ver los usuarios con preferencia de movimiento reducido?
- ¿El diseño puede degradarse a una barra de progreso estática o a una revelación sin animación?
- ¿Existen ancestros sticky, con transformaciones o virtualizados que cambien el bloque de contención?
Estructura de respuesta en 30 segundos
“Usaría una línea de tiempo de progreso de scroll para el progreso de la página y una línea de tiempo de progreso de vista para las tarjetas que entran en el scroll. Definiría una línea base estática y legible, para luego mejorarla dentro de una consulta de características con animation-timeline declarado después de la propiedad abreviada de animación. Animaría transform u opacity, probaría contenedores con scroll anidados y elementos sticky, y desactivaría el movimiento no esencial bajo prefers-reduced-motion. Verificaría la compatibilidad, el costo por cuadro, el acceso por teclado y la comprensión del contenido antes del despliegue.”
Respuesta detallada paso a paso
Paso 1: Seleccionar la línea de tiempo.
Usa una línea de tiempo de progreso de scroll cuando la animación se mapee al rango de desplazamiento de un contenedor. Usa una línea de tiempo de progreso de vista cuando la animación se mapee al recorrido de un elemento a través del scrollport.
Paso 2: Construir una línea base.
Renderiza primero el indicador de progreso y las tarjetas en un estado estático útil. Un navegador que ignore la animación aún debe exponer el contenido, el orden, el contraste y los controles.
Paso 3: Agregar la mejora con CSS.
@supports (animation-timeline: scroll()) {
.progress {
animation: grow-progress linear both;
animation-timeline: scroll(root block);
}
.card {
animation: reveal linear both;
animation-timeline: view(block);
animation-range: entry 0% cover 35%;
}
}Declara animation-timeline después de la propiedad abreviada porque esta última restablece las subpropiedades relacionadas con la línea de tiempo. Nombra la línea de tiempo explícitamente cuando los contenedores con scroll anidados puedan hacer que el contenedor más cercano sea ambiguo.
Paso 4: Mantener económicas las propiedades animadas.
Prefiere opacity y transform. Evita animar width, height, top, left o sombras grandes en una lista larga a menos que el perfilado demuestre que el costo es aceptable. No agregues will-change a cada tarjeta por suposición.
Paso 5: Manejar el movimiento reducido.
@media (prefers-reduced-motion: reduce) {
.progress,
.card {
animation: none;
transform: none;
opacity: 1;
}
}El contenido y el significado del progreso deben permanecer disponibles sin animación. Un estado instantáneo sutil o un indicador estático es más seguro que simplemente acortar una transición larga.
Paso 6: Probar la geometría y la compatibilidad.
Prueba el scroller raíz, scrollers anidados horizontales y verticales, elementos sticky, contenido dinámico, zoom, navegación por teclado y cambios en el viewport móvil. La detección de características debe controlar la mejora, no ocultar la línea base.
Paso 7: Medir y observar.
Usa trazas de rendimiento en DevTools para verificar el trabajo de estilo, diseño, pintura y composición. Prueba una lista larga y un dispositivo móvil de baja potencia, y presta atención al contenido que se vuelva ilegible cuando una línea de tiempo no sea compatible o se interrumpa.
Respuesta de ejemplo de alta calidad
“La barra de progreso de la página utiliza scroll(root block) porque su valor es el rango de desplazamiento raíz. Cada tarjeta utiliza view(block) con un rango de entrada a cobertura (entry-to-cover) porque su revelación debe seguir su propia visibilidad. Primero renderizo las tarjetas normalmente y luego agrego las líneas de tiempo dentro de @supports; la declaración se ubica después de la propiedad abreviada de animación. Limito el movimiento a transform y opacity, elimino la animación no esencial para usuarios con movimiento reducido y nombro el scroller cuando el anidamiento vuelve ambiguo el contenedor más cercano. Pruebo el acceso por teclado, el contenido sticky y dinámico, navegadores no compatibles y una lista larga en móviles mediante trazas de rendimiento.”
Errores comunes
- Usar un evento de scroll para cada cuadro → el trabajo del manejador puede competir con el desplazamiento → prefiere una línea de tiempo CSS cuando la relación sea declarativa.
- Confundir
scroll()yview()→ la animación comienza en el momento equivocado → mapea la línea de tiempo al progreso del contenedor o a la visibilidad del elemento. - Colocar
animation-timelineantes de la propiedad abreviada → la propiedad abreviada puede restablecerlo → declara la línea de tiempo después. - Animar propiedades de diseño por defecto → las páginas largas pueden desencadenar un trabajo costoso → comienza con transform y opacity, luego realiza un perfilado.
- Desplegar movimiento sin gestionar el movimiento reducido → los usuarios pierden el control sobre su preferencia → proporciona un estado estático.
- Ocultar el contenido hasta que haya soporte para animaciones → los navegadores sin soporte pierden información → construye primero la línea base.
- Asumir que el scroller más cercano es el correcto → los contenedores anidados cambian la línea de tiempo → nombra o prueba el scroller previsto.
Preguntas de seguimiento y respuestas
Pregunta de seguimiento 1: ¿Cuál es la diferencia entre scroll() y view()?
scroll() rastrea el progreso de un contenedor con scroll. view() rastrea la progresión de la visibilidad de un elemento a través del scrollport de ese contenedor.
Pregunta de seguimiento 2: ¿Por qué la línea de tiempo debe ir después de la propiedad abreviada?
La propiedad abreviada animation restablece las subpropiedades relacionadas con la línea de tiempo, por lo que una declaración de línea de tiempo previa puede quedar anulada.
Pregunta de seguimiento 3: ¿Cuál es la alternativa de respaldo (fallback)?
Mantener el contenido visible en su estado legible final y usar un indicador de progreso estático o una pequeña mejora en JavaScript únicamente cuando el requerimiento del producto realmente lo exija.
Pregunta de seguimiento 4: ¿Cómo das soporte a movimiento reducido?
Desactiva las animaciones no esenciales, elimina las transformaciones y preserva el mismo contenido y significado de estado mediante un estilo estático.
Pregunta de seguimiento 5: ¿Se puede animar height?
Solo después de perfilar el rendimiento y con una necesidad clara. Transform y opacity habitualmente evitan el trabajo de layout; animar height puede invalidar el diseño en los elementos hermanos.
Pregunta de seguimiento 6: ¿Qué sucede en un scroller anidado?
El contenedor con scroll aplicable más cercano puede diferir de la página. Prueba la geometría y nombra la línea de tiempo deseada o usa el argumento de scroller correcto.
Pregunta de seguimiento 7: ¿Cómo lo verificas en producción?
Registra el uso de soporte, trazas de rendimiento en dispositivos representativos, el comportamiento de movimiento reducido y comprobaciones de accesibilidad. Mantén la línea base estática para que las líneas de tiempo no compatibles o interrumpidas sigan siendo utilizables.