כמו שאילתות בקונטיינר, אבל לשאילתות תקועות, שאילתות עם 'צירוף' ושאילתות עם 'חריגה ממלאי'.
תאריך פרסום: 15 בינואר 2025
ב-Chrome 133 אנחנו משיקים שאילתות קונטיינר של מצב גלילה, שמבוססות על שאילתות קונטיינר. עכשיו אפשר לשלוח שאילתות לגבי המצב המנוהל בדפדפן של מיקום דביק, נקודות הצמדה לגלילה ורכיבים שניתנים לגלילה, ולהתאים אותו מ-CSS.
סקירה כללית
לפני ששולחים שאילתות לגבי מצב הגלילה, צריך להשתמש ב-JavaScript כדי להבין אם רכיב תקוע, מוצמד או ניתן לגלילה. עכשיו יש שיטה יעילה יותר במסלול לתקנים לקבלת המידע הזה ולהתאמה בהתאם. יש גם דרך חדשה להפעיל אנימציות, שמאפשרת להפעיל אנימציה מ-CSS בתגובה לגלילה.
לפניכם סקירה כללית על שאילתות המצב הזמינות מ-Chrome 133:
- מצב תקוע:
- הסגנון של הטריגר משתנה כשרכיב מוצמד לקצה.
- מצב 'צילום מסך':
- הסגנון של הטריגר משתנה כשרכיב מוצמד לציר.
- מצב שניתן לגלילה:
- שינוי סגנון ההפעלה כשהאלמנט חורג מעבר למסגרת.
החדשות הטובות הן שכל מה שלמדתם משאילתות בקונטיינרים יעזור לכם לעבוד עם שאילתות של מצב גלילה.
יש גם תחום לא מפותח בין אנימציות שמבוססות על גלילה לשאילתות של מאגרי נתונים של מצב גלילה. אנחנו צריכים להתנסות בתזמון ובהקשר כדי לגלות אם אנימציה שמבוססת על גלילה או אנימציה שמופיעה בתגובה לגלילה יהיו האפשרויות הטובות ביותר. הסרטון והדגמה הבאים מדגימים את הבעיה: הנפשה עם מיקום קבוע בהשוואה להנפשה שמופיעה בזמן גלילה.
(שמאל) אנימציה שהופעל על ידי scroll-state(), (ימין) אנימציה שמבוססת על גלילה
https://codepen.io/web-dot-dev/pen/emOrBaV
השאילתה הראשונה לגבי מצב גלילה
השלב הראשון הוא להגדיר את המאגר, באמצעות ערך חדש למאפיין container-type
. בדומה לשאילתה בקונטיינר, הרכיב שרוצים לשלוח עליו שאילתה הוא זה שנותנים לו את הערך container-type
, ואם רוצים, גם את הערך container-name
. בשאילתות של מצב גלילה, נותנים לרכיב שמצמיד, תקוע או שיש בו זליגת נתונים את הערך container-type: scroll-state
.
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
}
השלב השני הוא לבחור את הצאצא של הקונטיינר הזה שישיב למצב. בדומה לשאילתות של קונטיינרים, זה לא יכול להיות אותו רכיב שמכיל את container-type
.
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
> nav {
@container scroll-state(stuck: top) {
background: Highlight;
color: HighlightText;
}
}
}
השלב השלישי הוא לנסות את הכלי. בדוגמה הבאה ל-CSS, הרקע יהיה אדום כשהאלמנט .stuck-top
ידבק בחלק העליון ב-0
. בעזרת כמה שורות נוספות בקוד ה-CSS שכבר היינו כותבים, ורכיב מכיל נוסף שמציג את מצב הדפדפן, הרכיבים שלנו מבינים טוב יותר את הסביבה שלהם.
שיפור הדרגתי
בעזרת כלל at-rule @supports
והעיצוב בתצוגת עץ, אפשר להוסיף שיפורים הדרגתיים או שימוש בתכונות מותנות בכמה שורות קוד בלבד:
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
@supports (container-type: scroll-state) {
> nav {
@container scroll-state(stuck: top) {
background: Highlight;
color: HighlightText;
}
}
}
}
בנוסף, אם אתם משתמשים באנימציה של רכיבים בדף באמצעות שאילתות של מצב גלילה, חשוב לזכור להשתמש ב-@media (prefers-reduced-motion: no-preference) {}
סביב התנועה.
תרחישים לדוגמה
ללא שינוי
אולי כדאי לקרוא לקטע הזה 'מצבים דביקים'? זהו אוסף קטן של תרחישי שימוש למצבים דביקים, וגם קטע בונוס של רעיונות שצריך לפתח.
@container scroll-state(stuck: top) {}
@container scroll-state(stuck: bottom) {}
הוספת צל כאשר נתקעים
אחד מתרחישי השימוש הנפוצים ביותר לשאילתה תקועה הוא בסרגלי ניווט שרוצים להוסיף box-shadow
כשהם תקועים, כדי שהם יוכלו להיראות כאילו הם צפים מעל התוכן שהם מכסים.
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
> nav {
transition: box-shadow .3s ease;
@container scroll-state(stuck: top) {
box-shadow: var(--shadow-5);
}
}
}
הפעלת הכותרת הנוכחית שנתקעה
תרחיש נפוץ נוסף של משוב על ממשק משתמש דביק הוא הדגשת הרכיב הנדבק. ברשימה של להקות שממוינות לפי סדר אלפביתי, האפשרות הזו יכולה להיות מאוד מועילה ותומכת בחוויית השימוש.
.sticky-slide {
dt {
container-type: scroll-state;
position: sticky;
inset-block-start: 0;
inset-inline: 0;
> header {
transition:
background .3s ease,
box-shadow .5s ease;
@container scroll-state(stuck: top) {
background: hsl(265 100% 27%);
box-shadow: 0 5px 5px #0003;
}
}
}
}
זוהי וריאציה נוספת, שבה הכותרות מופיעות לצד הפריטים ברשימה. יש המון אפשרויות!
רעיונות נוספים
הנה רשימה של הדגמות של מודעות דביקות שיכולות לעורר בכם השראה להוסיף קצת פלפל לדגמה, או להסיר את ה-JavaScript שלהן, באמצעות שאילתות של מצב גלילה. מומלץ לנסות ליצור אתר שמתאים לך. כך התחביר והרעיונות יישארו בזיכרון 😏.
- https://codepen.io/BlogFire/pen/PoGMjaX – וריאנט של פתקיות דביקות
- https://codepen.io/mikegolus/pen/jOZzRzw – הוספת צללים לטבלה כשהיא מודבקת
- https://codepen.io/MarcRay/pen/PomBeP – סרגל הניווט התחתון מופיע בכותרת כשמופעל הטריגר
- https://codepen.io/kevinpowell/pen/OqKJjK – חשיפת סרגל הניווט התחתון
- https://codepen.io/abhisekz-the-decoder/pen/eKaLRd – כותרות של כרטיסים דביקים
- https://codepen.io/tutsplus/pen/abojPjP – צל של כותרת התמחור בטריגר
- https://codepen.io/kevinpowell/pen/KEjMEv – כותרות של חלונית צד עם קטעים מוצמדים
סיכום שנתי בתמונות
בעזרת שאילתות של מצב מוצמד, אנחנו יכולים להסיר חלק מהאחריות מ-JavaScript ומ-Snap Events ולהעביר את הטיפול ל-CSS.
@container scroll-state(snapped: x) {}
@container scroll-state(snapped: y) {}
@container scroll-state(snapped: inline) {}
@container scroll-state(snapped: block) {}
תזכורת קטנה, למקרה שדילוגתם על הקטע השאילתה הראשונה של מצב גלילה, המארז של שאילתה של הצמדה הוא האלמנט עם scroll-snap-align
, והאלמנט שיכול להתאים את עצמו חייב להיות צאצא של האלמנט הזה. כלומר, יש שלושה רכיבים שצריך להגדיר כדי לעשות זאת:
a scroll container with `scroll-snap-type`
⤷ a snap target with both `scroll-snap-align` and `container-type: scroll-state`
⤷ a child of the snap target that can query the container for snap state
שיפור המראה של הפריט שנלכד
כשמשתמשים בגלילה עם הצמדה למרכז, מקובל מאוד להדגיש או להציג את הפריט שמחובר למרכז. בדוגמה הזו של המלצות, נעשה שימוש במילות המפתח not
כדי שכל ההמלצות שלא צולמו ב-Snap יקבלו רמת שקיפיות נמוכה, בעוד שההמלצות שצולמו ב-Snap יוצגו במצב התצוגה הטבעי שלהן.
.demo {
overflow: auto hidden;
scroll-snap-type: x mandatory;
> article {
container-type: scroll-state;
scroll-snap-align: center;
@supports (container-type: scroll-state) {
> * {
transition: opacity .5s ease;
@container not scroll-state(snapped: x) {
opacity: .25;
}
}
}
}
}
הצגת הכותרת של הפריט שנצמד
זוהי דוגמה טובה לאופן שבו שאילתות לגבי מצב גלילה מאפשרות להפעיל אנימציה בתגובה לגלילה. זו גם דוגמה טובה למקרה שבו כדאי להשתמש ב-CSS עם העדפה לצמצום התנועה.
.demo {
overflow-x: auto;
scroll-behavior-x: contain;
scroll-snap-type: x mandatory;
> .card {
container-type: scroll-state;
scroll-snap-align: center;
@supports (container-type: scroll-state) {
@media (prefers-reduced-motion: no-preference) {
figcaption {
transform: translateY(100%);
@container scroll-state(snapped: x) {
transform: translateY(0);
}
}
}
}
}
}
אנימציה ברכיבי השקף
כשנותנים הרצאה, מאוד נפוץ להוסיף אנימציה לרכיבים של מופע שקפים או מצגת. בעבר היה די מעצבן לכתוב למטרה הזו משתמש למעקב אחרי צמתים, שכל מה שהוא עשה היה להגדיר סיווג לשקופית. עכשיו אין צורך ב-JavaScript.
html {
scroll-snap-type: y mandatory;
}
section {
container-type: scroll-state;
scroll-snap-align: start;
scroll-snap-stop: always;
@supports (container-type: scroll-state) {
@media (prefers-reduced-motion: no-preference) {
> h1 {
transition: opacity .5s ease, transform .5s var(--ease-spring-3);
transition-delay: .5s;
opacity: 0;
transform: scale(1.25);
@container scroll-state(snapped: block) {
opacity: 1;
transform: scale(1);
}
}
}
}
}
יכול להיות שתבחינו שכל השאילתות של מצב CSS שנשמרו מתנהגות כמו scrollsnapchanging
, בניגוד ל-scrollsnapchange
. כך תקבלו את האפשרות המוקדם ביותר לספק משוב חזותי לגבי הרכיב שנצמד. אם האירוע מתרחש מוקדם מדי, כדאי להשתמש באירוע JavaScript.
ניתן לגלילה
השאילתה לגבי מצב הגלילה תעזור מאוד להציג תכונות חזותיות שמאפשרות לדעת מתי אפשר לגלול באזור גלילה. לפני שאפשר היה להריץ שאילתות לגבי מצב הגלילה, היה קשה לדעת מה המצב.
@container scroll-state(scrollable: top) {}
@container scroll-state(scrollable: right) {}
@container scroll-state(scrollable: bottom) {}
@container scroll-state(scrollable: left) {}
סימון גלילה באמצעות צללים
יש טריק CSS מפורסם של Lea Verou שמשתמש ב-background-attachment: local
כדי להשיג אפקט דומה, וגם דרך לעשות זאת באמצעות אנימציה שמבוססת על גלילה. לכל שיטה יש יתרונות וחסרונות, ועלינו לבדוק מתי ואיפה כל אחת מהשיטות האלה מתאימה ביותר.
בדוגמה הבאה נעשה שימוש ברכיב דביק אחד שמשתרע על פני חלון הגלילה. כשהשאילתה של מצב הגלילה לפי הקשר חלה על העברה מדורגת בחלק העליון ועל העברה מדורגת בחלק התחתון, האטימות שלהן מונפשת באמצעות @property
: @container scroll-state(scrollable: top)
.
שימו לב גם שזהו המאגר הראשון שהוא גם מאגר size
וגם מאגר scroll-state
.
.scroll-container {
container-type: scroll-state size;
overflow: auto;
&::after {
content: " ";
background: var(--_shadow-top), var(--_shadow-bottom);
transition:
--_scroll-shadow-color-1-opacity .5s ease,
--_scroll-shadow-color-2-opacity .5s ease;
@container scroll-state(scrollable: top) {
--_scroll-shadow-color-1-opacity: var(--_shadow-color-opacity, 25%);
}
@container scroll-state(scrollable: bottom) {
--_scroll-shadow-color-2-opacity: var(--_shadow-color-opacity, 25%);
}
}
}
הנחיה עם חץ
לפעמים הצגת חץ יכולה לעזור למשתמשים להבין שאפשר לגלול באזור מסוים. הם נוטים להצביע בכיוון שבו יכולה להתרחש גלילה, ונעלמים כשאין בהם יותר צורך. אפשר לעשות זאת באמצעות הקוד הבא.
@container scroll-state((scrollable: top) or (not (scrollable: bottom))) {
translate: 0 calc(100% + 10px);
}
@container scroll-state((scrollable: top) and (not (scrollable: bottom))) {
translate: 0 calc(100% + 10px);
rotate: .5turn;
}
חזרה לראש הדף
אינטראקציה פופולרית נוספת במצב גלילה היא הלחצן הנוח 'גלילה לראש'. הקוד הבא גורם ללחצן הגלילה לחלק העליון להיעלם כשאין לאן לגלול למעלה.
הפתרון הזה הוא קצת הפוך, אבל הוא מאפשר לצמצם את כמות ה-CSS. מיקום העצירה הטבעי של הלחצן הוא בתצוגה, לכן צריך להורות לו להסתתר כשאין יותר אפשרות לגלול למעלה.
@container not scroll-state(scrollable: top) {
translate: 0 calc(100% + 10px);
}
המשך המחקר
רוצים לקבל מידע נוסף? ריכזנו כאן כמה מקורות מידע, החל מפרטים על המפרט ועד למאמרים מועילים נוספים בנושא:
- מה עוד נוכל לבצע שאילתות בקונטיינר? https://github.com/w3c/csswg-drafts/issues/5989
- הסבר על scroll-state() – https://drafts.csswg.org/css-conditional-5/scroll_state_explainer.md
- מפרט CSS של scroll-state() – https://www.w3.org/TR/css-conditional-5/#scroll-state-container
- צילום קובץ snapshot של הפריסה בלולאת האירועים של HTML
- פרק פודקאסט בנושא שאילתות מצב – https://nerdy.dev/the-css-podcast-on-state-queries
- מאמרים נוספים
- https://utilitybend.com/blog/is-the-sticky-thing-stuck-is-the-snappy-item-snapped-a-look-at-state-queries-in-css/
- https://ishadeed.com/article/css-state-queries/
- https://csscade.com/can-you-detect-overflow-with-css/
- https://css-tip.com/overflow-detection/ – זיהוי באמצעות אנימציה שמבוססת על גלילה, כך שגם אנשים שאינם ילדים יכולים לזהות אותה (עם החיסרון של הטריק)