A modo de resumen
La propiedad CSS overscroll-behavior permite que los desarrolladores anulen el comportamiento predeterminado de desplazamiento de desbordamiento del navegador cuando se llega a la parte superior o inferior del contenido. Los casos de uso incluyen inhabilitar la función de deslizar hacia abajo para actualizar en dispositivos móviles, quitar los efectos de resplandor de sobredesplazamiento y de banda elástica, y evitar que el contenido de la página se desplace cuando está debajo de un modal o una superposición.
Fondo
Límites de desplazamiento y encadenamiento de desplazamiento
El desplazamiento es una de las formas más fundamentales de interactuar con una página, pero ciertos patrones de UX pueden ser difíciles de manejar debido a los comportamientos predeterminados peculiares del navegador. Por ejemplo, considera un panel de apps con una gran cantidad de elementos por los que el usuario puede tener que desplazarse. Cuando llegan al final, el contenedor de desbordamiento deja de desplazarse porque no hay más contenido para consumir. En otras palabras, el usuario alcanza un "límite de desplazamiento". Pero observa lo que sucede si el usuario sigue desplazándose. El contenido detrás del panel lateral comienza a desplazarse. El contenedor superior se encarga del desplazamiento, es decir, la página principal en el ejemplo.
Resulta que este comportamiento se llama encadenamiento de desplazamiento, el comportamiento predeterminado del navegador cuando se desplaza el contenido. A menudo, el valor predeterminado es bastante bueno, pero, a veces, no es deseable o incluso es inesperado. Es posible que algunas apps quieran proporcionar una experiencia del usuario diferente cuando el usuario alcanza un límite de desplazamiento.
El efecto de deslizar hacia abajo para actualizar
Deslizar hacia abajo para actualizar es un gesto intuitivo que se popularizó con apps para dispositivos móviles, como Facebook y Twitter. Si deslizas el dedo hacia abajo en un feed de redes sociales y lo sueltas, se crea un espacio nuevo para que se carguen las publicaciones más recientes. De hecho, esta UX en particular se volvió tan popular que los navegadores para dispositivos móviles, como Chrome en Android, adoptaron el mismo efecto. Si deslizas el dedo hacia abajo en la parte superior de la página, se actualizará toda la página:
cuando se actualiza un feed en su AWP.
actualiza toda la página.
En situaciones como la PWA de Twitter,
puede ser conveniente inhabilitar la acción nativa de deslizar hacia abajo para actualizar. ¿Por qué? En esta app, es probable que no quieras que el usuario actualice la página por accidente. También es posible que veas una animación de actualización doble. Como alternativa, puede ser
mejor personalizar la acción del navegador y alinearla más con la marca
del sitio. Lo malo es que este tipo de personalización es difícil de lograr. Los desarrolladores terminan escribiendo JavaScript innecesario, agregan objetos de escucha táctiles no pasivos (que bloquean el desplazamiento) o pegan toda la página en un <div> de 100 vw/vh (para evitar que la página se desborde). Estas soluciones alternativas tienen efectos negativos bien documentados en el rendimiento del desplazamiento.
¡Podemos hacerlo mejor!
Presentamos overscroll-behavior
La propiedad overscroll-behavior es una nueva función de CSS que controla el comportamiento de lo que sucede cuando te desplazas más allá del límite de un contenedor (incluida la página en sí). Puedes usarla para cancelar el encadenamiento de desplazamiento, inhabilitar o personalizar la
acción de deslizar hacia abajo para actualizar, inhabilitar los efectos de banda elástica en iOS (cuando Safari
implemente overscroll-behavior) y mucho más.
Lo mejor es que usar overscroll-behavior no afecta negativamente el rendimiento de la página, como los trucos que se mencionaron en la introducción.
La propiedad toma tres valores posibles:
- auto: Es el valor predeterminado. Los desplazamientos que se originan en el elemento pueden propagarse a los elementos superiores.
- contain: Evita el encadenamiento de desplazamiento. Los desplazamientos no se propagan a los elementos superiores, pero se muestran los efectos locales dentro del nodo. Por ejemplo, el efecto de brillo de sobredesplazamiento en Android o el efecto de banda elástica en iOS, que notifican al usuario cuando alcanza un límite de desplazamiento. Nota: El uso de
overscroll-behavior: containen el elementohtmlevita las acciones de navegación de sobredesplazamiento. - none: Es igual que
contain, pero también evita los efectos de sobredesplazamiento dentro del nodo (p.ej., el brillo de sobredesplazamiento de Android o el efecto de banda elástica de iOS).
Analicemos algunos ejemplos para ver cómo usar overscroll-behavior.
Evita que los desplazamientos se escapen de un elemento de posición fija
Situación del cuadro de chat
Considera un cuadro de chat con posición fija que se ubique en la parte inferior de la página. La intención es que el cuadro de chat sea un componente independiente y que se desplace por separado del contenido que se encuentra detrás de él. Sin embargo, debido al encadenamiento de desplazamiento, el documento comienza a desplazarse en cuanto el usuario llega al último mensaje del historial de chat.
En esta app, es más apropiado que los desplazamientos que se originan dentro del cuadro de chat permanezcan dentro del chat. Para lograrlo, podemos agregar overscroll-behavior: contain al elemento que contiene los mensajes de chat:
#chat .msgs {
overflow: auto;
overscroll-behavior: contain;
height: 300px;
}
Básicamente, creamos una separación lógica entre el contexto de desplazamiento del cuadro de chat y la página principal. El resultado final es que la página principal se mantiene fija cuando el usuario llega al principio o al final del historial de chat. Los desplazamientos que comienzan en el cuadro de chat no se propagan hacia afuera.
Situación hipotética de la superposición de páginas
Otra variación de la situación de "desplazamiento insuficiente" es cuando ves que el contenido se desplaza detrás de una superposición de posición fija. ¡Es hora de un sorteo
de overscroll-behavior! El navegador intenta ser útil, pero termina haciendo que el sitio parezca tener errores.
Ejemplo: Modal con y sin overscroll-behavior: contain:
Inhabilita la función de deslizar hacia abajo para actualizar
Desactivar la acción de deslizar hacia abajo para actualizar es una sola línea de CSS. Solo evita el encadenamiento de desplazamiento en todo el elemento que define el viewport. En la mayoría de los casos, es
<html> o <body>:
body {
/* Disables pull-to-refresh but allows overscroll glow effects. */
overscroll-behavior-y: contain;
}
Con esta simple adición, corregimos las animaciones de doble deslizamiento para actualizar en la demostración del cuadro de chat y, en su lugar, podemos implementar un efecto personalizado que use una animación de carga más prolija. Toda la bandeja de entrada también se desenfoca a medida que se actualiza:
Este es un fragmento del código completo:
<style>
body.refreshing #inbox {
filter: blur(1px);
touch-action: none; /* prevent scrolling */
}
body.refreshing .refresher {
transform: translate3d(0,150%,0) scale(1);
z-index: 1;
}
.refresher {
--refresh-width: 55px;
pointer-events: none;
width: var(--refresh-width);
height: var(--refresh-width);
border-radius: 50%;
position: absolute;
transition: all 300ms cubic-bezier(0,0,0.2,1);
will-change: transform, opacity;
...
}
</style>
<div class="refre>she<r"
div class=&qu><ot;l>oad<ing-bar"/div
div>< cla>ss=<"loading-bar"></div>
<div class="loading><-bar>&<quot>;/<div
div class=&q><uot;loading><-bar&quo>t;</div
/>div
section id="inbox"!-- msgs --/section
script
let _startY;
const inbox = document.querySel>ector('#inbox');
inbox.addEventListener('touchstart', e = {
_startY = e.touches>[0].pageY;
}, {passive: true});
inbox.addEventListener('touchmove', e = {
const y = e.touches[0].pageY;
// Activate custom pull-to-refresh effects when at the top of the container&&
> // and &&user is scrolling up.
if (document.scrollingElement.scrollTop === 0 y _startY
!document.body.class<List.co>ntains('refreshing')) {
// refresh inbox.
}
}, {passive: true});
/script
Inhabilita los efectos de brillo y de banda elástica del sobredesplazamiento
Para inhabilitar el efecto de rebote cuando se alcanza un límite de desplazamiento, usa overscroll-behavior-y: none:
body {
/* Disables pull-to-refresh and overscroll glow effect.
Still keeps swipe navigations. */
overscroll-behavior-y: none;
}
Demostración completa
En resumen, la demostración completa del cuadro de chat usa overscroll-behavior para crear una animación personalizada de deslizar hacia abajo para actualizar y, además, inhabilitar los desplazamientos que se escapan del widget del cuadro de chat. Esto proporciona una experiencia del usuario óptima que habría sido difícil de lograr sin overscroll-behavior de CSS.