אמ;לק
המאפיין CSS overscroll-behavior
מאפשר למפתחים לשנות את התנהגות ברירת המחדל של דפדפן בגלילה במקרה של עומס יתר כשמגיעים לחלק העליון או התחתון של התוכן. דוגמאות לתרחישים לדוגמה: השבתת התכונה 'משיכה לרענון' בנייד, הסרת האפקטים של התאורה והאלסטיות בזמן גלילה, מניעת גלילה של תוכן הדף כשהוא נמצא מתחת למודל או לשכבת-על.
רקע
גבולות גלילה ושרשור גלילה
גלילה היא אחת מהדרכים הבסיסיות ביותר ליצור אינטראקציה עם דף, אבל יכול להיות שיהיה קשה להתמודד עם דפוסי UX מסוימים בגלל התנהגויות ברירת המחדל המוזרות של הדפדפן. לדוגמה, תצוגת האפליקציות עם מספר רב של פריטים שהמשתמש עשוי לגלול ביניהם. כשהם מגיעים לתחתית, הגלילה בקונטיינר של עודף התוכן נעצרת כי אין יותר תוכן לצרוך. במילים אחרות, המשתמש מגיע ל'גבול גלילה'. אבל שימו לב למה שקורה אם המשתמש ממשיך לגלול. התוכן מאחורי המגירה מתחיל לגלול! גלילה מתבצעת על ידי מאגר ההורה, כלומר הדף הראשי עצמו בדוגמה.
מסתבר שההתנהגות הזו נקראת שרשור גלילה, והיא ברירת המחדל של הדפדפן כשגוללים בתוכן. לרוב ברירת המחדל טובה, אבל לפעמים היא לא רצויה או לא צפויה. יכול להיות שאפליקציות מסוימות ירצו לספק חוויית משתמש שונה כשהמשתמש מגיע לגבול גלילה.
האפקט של 'משיכה לרענון'
'משיכה לרענון' היא מחווה אינטואיטיבית שצוברת פופולריות באפליקציות לנייד כמו Facebook ו-Twitter. משיכה למטה של פיד ברשת חברתית ושחרור יוצרים מקום חדש לטעינת פוסטים עדכניים יותר. למעשה, חוויית המשתמש הזו הפכה לפופולרית כל כך, שדפדפנים לנייד כמו Chrome ל-Android אימצו את אותו אפקט. החלקה למטה בחלק העליון של הדף מרעננת את כל הדף:
במצבים כמו PWA, יכול להיות שיהיה הגיוני להשבית את הפעולה המקורית של משיכה לרענון. למה? באפליקציה הזו, סביר להניח שלא תרצו שהמשתמש יגרום לרענון הדף בטעות. יכול להיות שתראו גם אנימציה כפולה של רענון. לחלופין, יכול להיות שיהיה נחמד יותר להתאים אישית את הפעולה של הדפדפן, כך שתתאים יותר למיתוג של האתר. הבעיה היא שסוג ההתאמה האישית הזה היה קשה לביצוע. המפתחים נאלצו לכתוב קוד JavaScript מיותר, להוסיף חיישנים לא פסיביים למגע (שחוסמים את הגלילה) או להדביק את כל הדף ב-100vw/vh<div>
(כדי למנוע מהדף לחרוג מעבר למסך). יש להן השפעות שליליות מוכרות על הביצועים של גלילה.
אנחנו יכולים לעשות טוב יותר!
חדש: 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
וללא 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-behavior-y: none
:
body {
/* Disables pull-to-refresh and overscroll glow effect.
Still keeps swipe navigations. */
overscroll-behavior-y: none;
}
הדגמה מלאה
בסיכום, בהדמו המלא של תיבת הצ'אט נעשה שימוש ב-overscroll-behavior
כדי ליצור אנימציה מותאמת אישית של 'משיכה לרענון' ולהשבית את האפשרות לגלול מחוץ לווידג'ט של תיבת הצ'אט. כך אפשר לספק חוויית משתמש אופטימלית, שיהיה קשה להשיג אותה בלי CSSoverscroll-behavior
.