כשפותחים רכיב <dialog> כמודל באמצעות showModal(), הדפדפן מקדם אותו לשכבה העליונה ומסמן את שאר המסמך כלא פעיל. הפעולה הזו חוסמת קליקים של מצביע העכבר ומיקוד מקלדת בדף שמתחת, אבל לא מונעת גלילה:
- גלילה בזמן שהסמן או תנועת המגע נמצאים מעל
::backdropגורמת לגלילה של הדף שמתחת. - גלילה בתוך
<dialog>עוברת לדף שמתחת ברגע שתיבת הדו-שיח מגיעה לגבול הגלילה שלה, או באופן מיידי אם התוכן של תיבת הדו-שיח לא חורג מהגבולות.
בהתאם למפרט של התכונה CSS Overscroll Behavior, הערך overscroll-behavior חל על כל הרכיבים של מאגרי גלילה, כולל מאגרי גלילה שלא ניתנים לגלילה (רכיבים עם overflow: hidden או overflow: auto שהתוכן שלהם לא חורג כרגע). אם משלבים את overscroll-behavior: contain ב-<dialog> עם overflow: hidden ו-overscroll-behavior: contain ב-dialog::backdrop, אפשר למנוע את הגלילה של הדף הבסיסי באמצעות CSS בלבד.
הטמעה
1. הכלת שרשור גלילה ב-<dialog>
גיליון הסגנונות של סוכן המשתמש מגדיר את overflow: auto ב-<dialog>, והופך אותו למאגר גלילה כברירת מחדל. מחילים את overscroll-behavior: contain (או none) על dialog:modal (או dialog).
2. הפיכת ::backdrop למאגר גלילה והכלת הגלילה שלו
כברירת מחדל, ל-dialog::backdrop יש overflow: visible, כלומר הוא לא מאגר גלילה ומתעלם מ-overscroll-behavior. צריך להגדיר את overflow: hidden ב-dialog::backdrop כדי להפוך אותו למאגר גלילה שלא ניתן לגלול, ולשייך אותו ל-overscroll-behavior: contain כך שתנועות הגלילה שמבוצעות מעל הרקע נלכדות ולא מגיעות למסמך שמתחת.
קוד לדוגמה
dialog:modal {
/* MANDATORY: Prevent scroll gestures inside the modal (even when its content
does not overflow) from chaining to the underlying page. */
overscroll-behavior: contain;
}
dialog::backdrop {
/* MANDATORY: ::backdrop defaults to overflow: visible (not a scroll container).
Set overflow: hidden so it becomes a non-scrollable scroll container that
honors overscroll-behavior. */
overflow: hidden;
overscroll-behavior: contain;
}
שיטות מומלצות ומגבלות
- חובה: מגדירים את
overscroll-behavior: containברכיב<dialog>עצמו (באמצעות הסלקטורdialog:modal) וב-dialog::backdrop. בלי ההצהרה הזו, תנועות גלילה מעל הרקע או בתוך תיבת הדו-שיח עדיין יקושרו לדף. - חובה: מגדירים את
overflow: hidden(אוoverflow: auto) ב-dialog::backdropכדי שיהפוך לקונטיינר גלילה. בלי ההצהרה הזו, ברירת המחדל של::backdropהיאoverflow: visible, ול-overscroll-behaviorלא תהיה השפעה. - אל תשתמשו ב-
overflow: clipאו ב-overflow: visibleב-dialog::backdropאו ב-dialog. אף אחד מהערכים לא יוצר מאגר גלילה, ולכן המאפייןoverscroll-behaviorלא יחול. - אל תפעילו את
overflow: hiddenאו אתposition: fixedעל<html>או על<body>כדי לנעול את הגלילה ברקע כשתיבת דו-שיח נפתחת. שינוי של גלישת הטקסט ברכיב הבסיסי מסיר את סרגל הגלילה של הדף (מה שגורם לשינוי בפריסה האופקית), יכול לאפס את מיקום הגלילה בדף או לגרום לו לקפוץ, ויכול לשבש רכיביposition: stickyבדף שמתחת.
שיטות חלופיות
המאפיין overscroll-behavior ב-CSS נתמך בכל הדפדפנים העיקריים במאגרי גלילה עם תוכן שחורג מהגבולות, אבל התמיכה ב-overscroll-behavior במאגרי גלילה שלא ניתן לגלול בהם היא מפרט חדש יותר שלא ניתן לזהות את התכונה שלו.
אל תנסו לזהות תכונות של תמיכה בקונטיינרים שלא ניתן לגלול באמצעות @supports (overscroll-behavior: contain) או CSS.supports('overscroll-behavior', 'contain'). כל הדפדפנים המודרניים תומכים בתחביר של המאפיין overscroll-behavior: contain ומחזירים את הערך true, גם אם הם אוכפים אותו רק כשהתוכן חורג מהגבולות.
במקום זאת, התייחסו להכלה של גלילה בקונטיינרים של גלילה שלא ניתנים לגלילה כשיפור הדרגתי (progressive enhancement):
- בדפדפנים שתומכים ב-
overscroll-behaviorבמאגרי גלילה שלא ניתנים לגלילה, הגלילה של דף הרקע נמנעת לחלוטין גם מעלdialog::backdropוגם בתוך<dialog>(בין אם התוכן שלו חורג ובין אם לא). - בדפדפנים שעדיין לא תומכים ב-
overscroll-behaviorבמאגרי גלילה שלא ניתנים לגלילה,overscroll-behavior: containב-dialogעדיין מונע שרשור גלילה בכל פעם שהתוכן של תיבת הדו-שיח עצמה חורג וניתן לגלילה. בינתיים,showModal()עדיין לוכד את מיקוד המקלדת ומסמן את מסמך הרקעinert. - מומלץ להסתמך על שיפור הדרגתי (progressive enhancement) במקום על פתרונות עקיפים מדור קודם שמחילים את
overflow: hiddenאוposition: fixedעל<html>או<body>, כי הוא לא מסיר את סרגל הגלילה הבסיסי, לא גורם לשינויים בפריסה האופקית, לא מקפיץ את מיקום הגלילה בדף ולא משבש רכיביposition: stickyבדף שמתחת.