TL;DR
La propriété CSS overscroll-behavior permet aux développeurs de remplacer le comportement de défilement par défaut du navigateur lorsqu'il atteint le haut ou le bas du contenu. Les cas d'utilisation incluent la désactivation de la fonctionnalité de glisser vers le bas pour actualiser sur mobile, la suppression des effets de lueur et de rebond lors du défilement hors limites, et l'empêchement du défilement du contenu de la page lorsqu'il se trouve sous une fenêtre modale ou une superposition.
Arrière-plan
Limites de défilement et chaînage du défilement
Le défilement est l'un des moyens les plus fondamentaux d'interagir avec une page, mais certains modèles d'expérience utilisateur peuvent être difficiles à gérer en raison des comportements par défaut du navigateur. Prenons l'exemple d'un panneau des applications contenant un grand nombre d'éléments que l'utilisateur peut avoir à faire défiler. Lorsqu'ils atteignent le bas, le conteneur de dépassement arrête de défiler, car il n'y a plus de contenu à consommer. En d'autres termes, l'utilisateur atteint une "limite de défilement". Mais remarquez ce qui se passe si l'utilisateur continue de faire défiler la page. Le contenu derrière le panneau latéral commence à défiler. Le défilement est pris en charge par le conteneur parent, c'est-à-dire la page principale elle-même dans l'exemple.
Ce comportement est appelé chaînage du défilement. Il s'agit du comportement par défaut du navigateur lors du défilement du contenu. Souvent, la valeur par défaut est plutôt bonne, mais parfois, elle n'est pas souhaitable, voire inattendue. Certaines applications peuvent vouloir offrir une expérience utilisateur différente lorsque l'utilisateur atteint une limite de défilement.
L'effet "glisser vers le bas pour actualiser"
Le geste "glisser vers le bas pour actualiser" est un geste intuitif popularisé par des applications mobiles telles que Facebook et Twitter. En tirant vers le bas sur un flux social et en relâchant, vous créez un nouvel espace pour charger des posts plus récents. En fait, cette expérience utilisateur particulière est devenue si populaire que les navigateurs mobiles comme Chrome sur Android ont adopté le même effet. Balayer l'écran vers le bas en haut de la page actualise l'intégralité de la page :
lors de l'actualisation d'un flux dans sa PWA.
actualise l'intégralité de la page.
Dans des situations telles que la PWA Twitter, il peut être judicieux de désactiver l'action native de glisser vers le bas pour actualiser. Pourquoi ? Dans cette application, vous ne voulez probablement pas que l'utilisateur actualise accidentellement la page. Vous pouvez également voir une double animation d'actualisation. Il peut également être plus agréable de personnaliser l'action du navigateur, en l'alignant plus étroitement sur l'image de marque du site. Malheureusement, ce type de personnalisation est difficile à réaliser. Les développeurs finissent par écrire du code JavaScript inutile, ajouter des écouteurs tactiles non passifs (qui bloquent le défilement) ou coller l'intégralité de la page dans un <div> de 100 vw/vh (pour éviter que la page ne déborde). Ces solutions de contournement ont des effets négatifs bien documentés sur les performances de défilement.
On peut faire mieux !
Découvrez overscroll-behavior
La propriété overscroll-behavior est une nouvelle fonctionnalité CSS qui contrôle le comportement d'un conteneur (y compris la page elle-même) lorsque vous faites défiler la page au-delà de ses limites. Vous pouvez l'utiliser pour annuler le chaînage de défilement, désactiver/personnaliser l'action de glisser vers le bas pour actualiser, désactiver les effets de rebond sur iOS (lorsque Safari implémente overscroll-behavior), etc.
Le principal avantage est que l'utilisation de overscroll-behavior n'a pas d'impact négatif sur les performances de la page, contrairement aux astuces mentionnées dans l'introduction.
La propriété peut prendre trois valeurs possibles :
- auto : valeur par défaut. Les défilements qui proviennent de l'élément peuvent se propager aux éléments ancêtres.
- contain : empêche le chaînage du défilement. Les défilements ne se propagent pas aux ancêtres, mais les effets locaux dans le nœud sont affichés. Par exemple, l'effet de lueur de défilement excessif sur Android ou l'effet de bande élastique sur iOS, qui avertit l'utilisateur lorsqu'il a atteint une limite de défilement. Remarque : L'utilisation de
overscroll-behavior: containsur l'élémenthtmlempêche les actions de navigation par défilement hors limites. - none : identique à
contain, mais empêche également les effets de défilement hors limites dans le nœud lui-même (par exemple, l'effet de halo de défilement hors limites d'Android ou l'effet d'élastique d'iOS).
Examinons quelques exemples pour voir comment utiliser overscroll-behavior.
Empêcher les défilements de sortir d'un élément à position fixe
Le scénario de la boîte de discussion
Prenons l'exemple d'une boîte de discussion à position fixe située en bas de la page. L'objectif est que la boîte de discussion soit un composant autonome et qu'elle défile séparément du contenu derrière elle. Toutefois, en raison du chaînage du défilement, le document commence à défiler dès que l'utilisateur atteint le dernier message de l'historique des discussions.
Pour cette application, il est plus approprié que les défilements provenant de la boîte de discussion restent dans la discussion. Pour ce faire, ajoutez overscroll-behavior: contain à l'élément qui contient les messages de chat :
#chat .msgs {
overflow: auto;
overscroll-behavior: contain;
height: 300px;
}
En gros, nous créons une séparation logique entre le contexte de défilement de la boîte de discussion et la page principale. Le résultat final est que la page principale reste en place lorsque l'utilisateur atteint le haut ou le bas de l'historique des discussions. Les défilements qui commencent dans la boîte de discussion ne se propagent pas vers l'extérieur.
Scénario de superposition de page
Une autre variante du scénario de "défilement sous un élément" est lorsque vous voyez du contenu défiler derrière une superposition à position fixe. Un indice flagrant
overscroll-behavior est de mise ! Le navigateur essaie d'être utile, mais il finit par donner l'impression que le site est défectueux.
Exemple : boîte de dialogue avec et sans overscroll-behavior: contain :
Désactiver le glisser vers le bas pour actualiser
Pour désactiver l'action "glisser vers le bas pour actualiser", il suffit d'une seule ligne de CSS. Il suffit d'empêcher le chaînage du défilement sur l'ensemble de l'élément définissant la fenêtre d'affichage. Dans la plupart des cas, il s'agit de <html> ou de <body> :
body {
/* Disables pull-to-refresh but allows overscroll glow effects. */
overscroll-behavior-y: contain;
}
Grâce à ce simple ajout, nous corrigeons les doubles animations de glisser vers le bas pour actualiser dans la démo de chatbox et pouvons à la place implémenter un effet personnalisé qui utilise une animation de chargement plus soignée. La boîte de réception entière devient également floue pendant son actualisation :
Voici un extrait du code complet :
<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
Désactiver les effets de lueur et de rebond lors du défilement hors limites
Pour désactiver l'effet de rebond lorsque vous atteignez une limite de défilement, utilisez overscroll-behavior-y: none :
body {
/* Disables pull-to-refresh and overscroll glow effect.
Still keeps swipe navigations. */
overscroll-behavior-y: none;
}
Démo complète
En résumé, la démo complète de la boîte de discussion utilise overscroll-behavior pour créer une animation personnalisée de glissement vers le bas pour actualiser et empêcher les défilements de sortir du widget de la boîte de discussion. Cela permet d'offrir une expérience utilisateur optimale, ce qui aurait été difficile à réaliser sans les overscroll-behavior CSS.