אמ;לק
המאפיין overscroll-behavior ב-CSS מאפשר למפתחים לשנות את התנהגות ברירת המחדל של הדפדפן לגלילה מעבר לגבולות התוכן, כשמגיעים לחלק העליון או התחתון של התוכן. תרחישי שימוש כוללים השבתה של התכונה "למשוך למטה לרענון" בנייד, הסרת אפקטים של גלילה מעבר לקצה ושל גלילה קפיצית, ומניעת גלילה של תוכן הדף כשהוא נמצא מתחת למודל או לשכבת-על.
רקע
גבולות גלילה ושרשור גלילה
גלילה היא אחת הדרכים הבסיסיות ביותר לאינטראקציה עם דף, אבל יכול להיות שיהיה קשה להתמודד עם דפוסי UX מסוימים בגלל התנהגויות ברירת המחדל המוזרות של הדפדפן. לדוגמה, נניח שיש חלונית הזזה לאפליקציות עם מספר גדול של פריטים שהמשתמש צריך לגלול ביניהם. כשהם מגיעים לתחתית, הגלילה בקונטיינר הגלישה נעצרת כי אין יותר תוכן. במילים אחרות, המשתמש מגיע ל "גבול הגלילה". אבל שימו לב מה קורה אם המשתמש ממשיך לגלול. התוכן שמאחורי התפריט הנשלף מתחיל להיגלל. הגלילה מתבצעת במאגר הראשי, שהוא הדף הראשי עצמו בדוגמה.
מסתבר שההתנהגות הזו נקראת שרשור גלילה, והיא התנהגות ברירת המחדל של הדפדפן כשגוללים בתוכן. הרבה פעמים ברירת המחדל היא די טובה, אבל לפעמים היא לא רצויה או אפילו לא צפויה. באפליקציות מסוימות, יכול להיות שתרצו לספק חוויית משתמש שונה כשהמשתמש מגיע לגבול הגלילה.
האפקט של משיכה למטה לרענון
משיכה למטה לרענון היא מחווה אינטואיטיבית שהפכה לפופולרית בזכות אפליקציות לנייד כמו פייסבוק וטוויטר. כשגוררים את הפיד ברשת החברתית כלפי מטה ומשחררים, נוצר מקום חדש לטעינת פוסטים עדכניים יותר. למעשה, חוויית המשתמש הספציפית הזו הפכה לכל כך פופולרית, שדפדפנים לנייד כמו Chrome ב-Android אימצו את אותו אפקט. החלקה למטה בחלק העליון של הדף מרעננת את כל הדף:
כשמרעננים פיד ב-PWA שלהם.
מרעננת את כל הדף.
במצבים כמו PWA של Twitter, יכול להיות שיהיה הגיוני להשבית את פעולת המשיכה למטה לרענון המקורית. למה? באפליקציה הזו, סביר להניח שאתם לא רוצים שהמשתמש ירענן את הדף בטעות. יכול להיות שגם תראו אנימציה של רענון כפול. לחלופין, יכול להיות שיהיה נחמד יותר להתאים אישית את הפעולה של הדפדפן, כך שתתאים יותר למיתוג של האתר. הבעיה היא שקשה ליישם את סוג ההתאמה האישית הזה. מפתחים כותבים קוד JavaScript מיותר, מוסיפים מאזינים לאירועי מגע לא פסיביים (שחוסמים את הגלילה) או מכניסים את כל הדף ל-<div> של 100vw/vh (כדי למנוע גלישה של הדף). לפתרונות העקיפים האלה יש השפעות שליליות מתועדות היטב על ביצועי הגלילה.
אנחנו יכולים לעשות את זה טוב יותר!
נעים להכיר: overscroll-behavior
המאפיין overscroll-behavior הוא תכונה חדשה של CSS שקובעת מה קורה כשגוללים מעבר לגבולות של מאגר (כולל הדף עצמו). אפשר להשתמש בו כדי לבטל שרשור גלילה, להשבית או להתאים אישית את פעולת המשיכה לרענון, להשבית אפקטים של גומי ב-iOS (כש-Safari מטמיע את overscroll-behavior) ועוד.
והחלק הכי טוב הוא שהשימוש ב-overscroll-behavior לא משפיע לרעה על ביצועי הדף, בניגוד לשיטות שהוזכרו במבוא.
למאפיין יש שלושה ערכים אפשריים:
- auto – ברירת המחדל. גלילות שמתחילות ברכיב עשויות להתפשט לרכיבים קודמים.
- contain – מונע שרשור גלילה. הגלילות לא מועברות לאבות הקדמונים, אבל מוצגות השפעות מקומיות בתוך הצומת. לדוגמה, אפקט הזוהר בגלילה מעבר לקצה ב-Android או אפקט הגומי ב-iOS, שמודיעים למשתמשים כשהם הגיעו לגבול הגלילה. הערה: שימוש ב-
overscroll-behavior: containברכיבhtmlמונע פעולות ניווט בגלילת יתר. - none – כמו
contain, אבל גם מונע אפקטים של גלילה מעבר לקצה בתוך הצומת עצמו (למשל, אפקט הזוהר של גלילה מעבר לקצה ב-Android או אפקט הגומי ב-iOS).
ריכזנו כאן כמה דוגמאות שמראות איך להשתמש ב-overscroll-behavior.
מניעת גלילה מחוץ לרכיב במיקום קבוע
תרחיש תיבת הצ'אט
ניקח לדוגמה תיבת צ'אט במיקום קבוע בתחתית הדף. המטרה היא שתיבת הצ'אט תהיה רכיב עצמאי, ושהגלילה בה תהיה נפרדת מהתוכן שמאחוריה. עם זאת, בגלל שרשור הגלילה, המסמך מתחיל להיגלל ברגע שהמשתמש מגיע להודעה האחרונה בהיסטוריית הצ'אט.
באפליקציה הזו, עדיף שגלילות שמתחילות בתיבת הצ'אט יישארו בתוך הצ'אט. כדי לעשות את זה, נוסיף את overscroll-behavior: contain לרכיב שמכיל את הודעות הצ'אט:
#chat .msgs {
overflow: auto;
overscroll-behavior: contain;
height: 300px;
}
בעצם, אנחנו יוצרים הפרדה לוגית בין הקשר הגלילה של תיבת הצ'אט לבין הדף הראשי. התוצאה הסופית היא שהדף הראשי נשאר במקום כשהמשתמש מגיע לחלק העליון או התחתון של היסטוריית הצ'אט. גלילות שמתחילות בתיבת הצ'אט לא מתפשטות החוצה.
תרחיש של שכבת-על בדף
וריאציה נוספת של תרחיש "גלילה מתחת לתוכן" היא כשרואים תוכן שנגלל מאחורי שכבת-על במיקום קבוע. הגיע הזמן לחלק
overscroll-behavior בחינם! הדפדפן מנסה לעזור, אבל בסופו של דבר האתר נראה כאילו יש בו באג.
דוגמה – מודל עם ובלי overscroll-behavior: contain:
השבתת האפשרות "למשוך למטה לרענון"
כדי להשבית את הפעולה "למשוך למטה לרענון", צריך להוסיף שורה אחת של CSS. פשוט מונעים את שרשור הגלילה בכל הרכיב שמגדיר את אזור התצוגה. ברוב המקרים, זה יהיה
<html> או <body>:
body {
/* Disables pull-to-refresh but allows overscroll glow effects. */
overscroll-behavior-y: contain;
}
בעזרת התוספת הפשוטה הזו, אנחנו מתקנים את האנימציות הכפולות של "למשוך למטה לרענון" בהדגמה של תיבת הצ'אט, ובמקום זאת יכולים להטמיע אפקט מותאם אישית שמשתמש באנימציית טעינה מסודרת יותר. כל תיבת הדואר הנכנס גם מטושטשת בזמן שהיא מתרעננת:
הנה קטע מהקוד המלא:
<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="refresher">
<div class="loading-bar"></div>
<div class="loading-bar"></div>
<div class="loading-bar"></div>
<div class="loading-bar"></div>
</div>
<section id="inbox"><!-- msgs --></section>
<script>
let _startY;
const inbox = document.querySelector('#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.classList.contains('refreshing')) {
// refresh inbox.
}
}, {passive: true});
</script>
השבתת האפקטים של גלילת יתר (overscroll) – הבהוב וגלילה קפיצית (rubberbanding)
כדי להשבית את אפקט ההקפצה כשמגיעים לגבול הגלילה, משתמשים ב-overscroll-behavior-y: none:
body {
/* Disables pull-to-refresh and overscroll glow effect.
Still keeps swipe navigations. */
overscroll-behavior-y: none;
}
הדגמה מלאה
כדי לחבר את כל החלקים, הדמו המלא של תיבת הצ'אט משתמש ב-overscroll-behavior כדי ליצור אנימציה מותאמת אישית של משיכה למטה לרענון, ולמנוע מהגלילות לצאת מהווידג'ט של תיבת הצ'אט. כך אפשר לספק חוויית משתמש אופטימלית, שהיה קשה להשיג בלי overscroll-behavior ב-CSS.