"משיכה לחשיפה" היא תבנית של ממשק משתמש שבה תוכן (כמו סרגל חיפוש או פקד רענון) מוסתר מעל החלק העליון של אזור שניתן לגלול בו בטעינה הראשונית, והמשתמש יכול למשוך כלפי מטה (לגלול למעלה) כדי לחשוף אותו. התבנית הזו נפוצה באפליקציות לנייד ובאפליקציות אינטרנט בשביל סרגלי חיפוש, מסננים ואמצעי בקרה משניים אחרים שצריכים להיות נגישים אבל לא גלויים באופן מיידי.
המאפיין scroll-initial-target של CSS מאפשר להטמיע את התבנית הזו באופן הצהרתי, באמצעות CSS בלבד. אם מגדירים את scroll-initial-target: nearest ברכיב התוכן הראשי, מאגר הגלילה יוצג כשהתוכן המוסתר נגלל אל מחוץ לתצוגה. בעבר, מפתחים הסתמכו על JavaScript (Element.scrollIntoView()) או על מזהי מקטעים של כתובות URL (#content-id) כדי לעשות את זה, אבל לשתי השיטות האלה יש מגבלות וקשה להטמיע אותן.
איך להטמיע
כדי להטמיע תבנית של משיכה לחשיפה:
- מוודאים שיש מאגר גלילה: רכיב היעד חייב להיות בתוך מאגר גלילה (רכיב עם גלישה שמאפשר גלילה, כמו
overflow: auto). זה יכול להיות כל רכיב אב, כולל רכיב הבסיס<html>. - הגדרת הרכיב המוסתר: ממקמים את התוכן שרוצים להסתיר (למשל, שורת חיפוש) כצאצא הראשון בתוך מאגר הגלילה. הרכיב הזה ייגלל אל מחוץ לתצוגה בטעינה הראשונית.
- הגדרת התוכן הראשי: ממקמים את רכיב התוכן הראשי מיד אחרי הרכיב המוסתר. זה הרכיב שהמשתמש צריך לראות קודם.
- טירגוט התוכן הראשי: מחילים את
scroll-initial-target: nearestעל רכיב התוכן הראשי, כדי שמאגר הגלילה יציג אותו כשהוא גלוי, ויסתיר את הרכיב שמעליו. - הוספת גלילה עם נקודות עצירה (scroll snapping): כדי לוודא שהרכיב המוסתר תמיד גלוי או מוסתר באופן מלא (ולא נשאר במצב של גלילה חלקית), מוסיפים את
scroll-snap-type: y mandatoryלקונטיינר הגלילה ואתscroll-snap-align: startגם לרכיב המוסתר וגם לרכיב התוכן הראשי.
קוד לדוגמה: גרירה כדי להציג את החיפוש
/**
* ANCESTOR: Define the scroll container.
* Scroll snapping ensures the search bar is always
* either fully visible or fully hidden.
*/
.scroll-container {
height: 100vh;
overflow-y: auto;
scroll-snap-type: y mandatory;
}
/**
* HIDDEN ELEMENT: The search bar hidden above the fold on load.
* It has scroll-snap-align so it snaps into place when pulled down.
*/
.search-bar {
height: 60px;
scroll-snap-align: start;
}
/**
* MAIN CONTENT + TARGET: The element the user sees first.
* scroll-snap-align makes it a valid snap point.
* scroll-initial-target tells the browser to scroll here on
* initial render, hiding the search bar above it.
*/
.main-content {
scroll-snap-align: start;
scroll-initial-target: nearest;
}
הטמעה אסטרטגית ושיטות מומלצות
- מומלץ להשתמש ב-
scroll-initial-target: nearestכשרוצים למשוך את תשומת הלב של המשתמש לחלק ספציפי באזור שניתן לגלילה בזמן הטעינה, ולהסתיר בכוונה יחידות ממשק משתמש היקפיות כמו סרגל חיפוש בחלק העליון. - אל תבלבלו בין זה לבין מיקוד נגישות. המאפיין הזה מזיז רק את אזור התצוגה החזותי, ולא את מיקוד המקלדת. אם היעד אמור להיות נקודת ההתחלה למשתמשים במקלדת, צריך לנהל את
element.focus()באופן ידני. - אל תשתמשו בזה אם אתם צריכים אנימציית "גלילה" חלקה בזמן הטעינה. המאפיין הזה הוא נפרד ומגדיר את המיקום באופן מיידי בשלב הפריסה.
- אל תגדירו את
scroll-initial-targetבכמה רכיבים באותו מאגר שניתן לגלול. אם יש כמה רכיבים שמציינים אתscroll-initial-target: nearest, הדפדפן בוחר את הרכיב שמופיע ראשון בסדר של עץ ה-DOM. - חשוב להביא בחשבון את היררכיית הקדימויות: פרגמנט URL (למשל,
example.com/#top) והמאפייןscroll-startברמת מאגר התגים מקבלים קדימות על פניscroll-initial-target.
אסטרטגיית גיבוי
בדפדפנים שעדיין לא תומכים ב-API, צריך להשתמש ב-JavaScript כחלופה. שימו לב: כדי למשוך תוכן ולחשוף אותו, התוכן הראשי צריך להיות קשור ל-start (החלק העליון) של מאגר התגים.
/**
* Progressive Enhancement Fallback
*/
document.addEventListener("DOMContentLoaded", () => {
// Check for native CSS support
if (!CSS.supports("scroll-initial-target", "nearest")) {
const targetContent = document.querySelector('.main-content.target');
if (targetContent) {
// Use behavior: "instant" to mimic the native CSS behavior
// 'block: start' should match your CSS 'scroll-snap-align' (or expected top position)
targetContent.scrollIntoView({ behavior: 'instant', block: 'start' });
}
}
});