סידור שינויים במקבצים שמגיעים למיקום:רכיבים קבועים

Tom Wiltzius
Tom Wiltzius

ב-Chrome 22, התנהגות הפריסה של רכיבי position:fixed שונה במקצת מזו של הגרסאות הקודמות. כל הרכיבים מסוג position:fixed יוצרים עכשיו הקשרים חדשים של סטאקינג. הפעולה הזו תשנה את סדר העריכה של דפים מסוימים, ויכול להיות שהיא תגרום לשיבושים בפריסות הדפים. ההתנהגות החדשה תואמת להתנהגות של דפדפני WebKit במכשירים ניידים (iOS Safari ו-Chrome ל-Android).

Stacking Whats?

כולם מכירים ומעריכים את z-index לצורך קביעת סדר העומק של רכיבים בדף. עם זאת, לא כל אינדקסי ה-z נוצרו שווים: הערך של z-index של רכיב קובע רק את הסדר שלו ביחס לרכיבים אחרים באותו הקשר של יצירת ערימות. רוב הרכיבים בדף נמצאים בהקשר סטאקינג יחיד ברמה הבסיסית, אבל רכיבים שממוקמים באופן מוחלט או יחסי עם ערכי z-index שאינם אוטומטיים יוצרים הקשרי סטאקינג משלהם (כלומר, כל הצאצאים שלהם ימוינו לפי ציר z בתוך הרכיב ההורה ולא ימוזגו עם תוכן מחוץ לרכיב ההורה). החל מגרסה 22 של Chrome, רכיבי position:fixed ייצרו גם הם הקשרים משלהם של עריכת שכבות.

המאמר הזה ב-MDN הוא סקירה כללית מצוינת על הקשרי עריכה.

משווים את position:fixed למאפיין החדש position:sticky: לידיעתכם, position:sticky יוצר תמיד הקשר חדש של סטאקינג.

למה בחרנו לעשות זאת?

דפדפנים לנייד (Mobile Safari, ‏ דפדפן Android, ‏ דפדפנים מבוססי Qt) מניחים רכיבים עם position:fixed בהקשרי סטאקינג משלהם, ועושים זאת כבר זמן מה (מאז iOS5, ‏ Android Gingerbread וכו') כי זה מאפשר לבצע אופטימיזציות מסוימות של גלילה, וכך דפי האינטרנט הופכים להיות הרבה יותר תגובה למגע. אנחנו משיקים את השינוי הזה במחשבים שולחניים מסיבות שלוש:

  1. התנהגות שונה של עיבוד בדפדפנים 'ניידים' ו'מחשבים' היא מכשול בפני מחברי אתרים. אם אפשר, CSS צריך לפעול באופן זהה בכל מקום.
  2. בטאבלטים, לא ברור איזה מבין האלגוריתמים ליצירת הקשר של מודעות מוערמות שמתאימים למכשירים ניידים או למחשבים הוא המתאים ביותר.
  3. הוספת אופטימיזציות של ביצועי גלילה מהנייד למחשב שולחני תורמת גם למשתמשים וגם לכותבים.

פרטי השינוי

דוגמה שבה מוצגות התנהגויות הפריסה השונות: https://codepen.io/paulirish/pen/CgAof

לאחר השינוי, שתי הגרסאות ייראו כמו הגרסה שבצד שמאל.

בדוגמה הזו, בתיבה הירוקה מופיע z-index: 1, בתיבה הוורודה מופיע z-index: 3 ובתיבה הכתומה מופיע z-index: 2. הקופסה הכחולה היא אב קדמון של הקופסה הכתומה, ויש לה את position:fixed.

אם לתיבת ה-Stacking של התמונה הכחולה יש הקשר משלה, הערך של z-index בתיבת ה-Stacking של התמונה הכתומה מחושב ביחס להקשר של תיבת ה-Stacking של התמונה הכחולה. מכיוון שלתיבה הכחולה יש ערך z-index של auto, כך שלרמת הערימה שלה יש ערך אפס בהקשר הערימה ברמה הבסיסית, התיבה הכתומה תופיע מאחורי התיבות הירוקה והורודה, שיש להן אינדקסי z של 1 ו-3 (בהתאמה) בהקשר ברמה הבסיסית.

אם התיבה הכחולה לא מקבלת הקשר סטאקינג משלה, הערך של z-index בתיבה הכתומה מחושב ביחס להקשר הסטאקינג ברמה הבסיסית (יחד עם התיבות הירוקה והורודה). לכן, התיבה הכתומה מסתיימת בחלוקה בין התיבות הוורודות והירוקות.

פרטים נוספים על הקריטריונים ליצירת הקשרים המוערמים (ועל האופן שבו הקשרים המוערמים מתנהגים באופן כללי) זמינים במאמר הזה ב-MDN. בדוגמה, בגרסה שבצד שמאל תמיד ניתנה לתיבת הכחול הקשר סטאקינג משלה כי השקיפות שלה נמוכה מ-1. שינוי ההתנהגות הזה מוסיף למעשה קריטריון נוסף ליצירת הקשר נפרד של סטאקינג, כלומר רכיב עם position:fixed.

בדיקות והעתיד

כדי לבדוק אם הדף ישתנה, עוברים אל about:flags ב-Chrome ומפעילים או משביתים את האפשרות 'רכיבים במיקום קבוע יוצרים הקשרי סטאק'. אם הפריסה נראית אותו דבר בשני המקרים, סימן שהכול תקין. אם לא, ודאו שהתוצאה נראית לכם מקובלת כשהדגל מופעל, כי זו תהיה ברירת המחדל ב-Chrome 22.

בעקבות השינוי הזה, היכולת לשלב תוכן בתוך עץ משנה של position:fixed עם תוכן שלא ניתן לגלילה מבחוץ הוסרה. סביר להניח שמפתחי אינטרנט לא עושים זאת בכוונה, ואפשר ליצור את אותו אפקט על ידי הקצאת חלקים שונים של DOM לכמה אלמנטים עם position:fixed. לדוגמה, אלה שתי דוגמאות:

https://codepen.io/wiltzius/pen/gcjCk

בדף הזה מנסים להציב שני רכיבי div צאצאים (overlayA ו-overlayB) של רכיב position:fixed, אחד מעל רכיב div נפרד של תוכן ואחד מתחת לאותו רכיב div נפרד של תוכן. עכשיו אי אפשר לעשות זאת כי רכיב position:fixed הוא הקשר סטאקינג משלו, והוא (יחד עם כל הצאצאים שלו) יופיע לגמרי מעל רכיב ה-div של התוכן או לגמרי מתחתיו. שימו לב שהדוגמה הזו פועלת ב-Chrome 21 ובגרסאות קודמות, אבל לא פועלת יותר ב-Chrome 22.

כדי לפתור את הבעיה, אפשר לפצל את שתי שכבות-העל לרכיבים משלהם עם position:fixed. כל אחד מהם הוא הקשר סטאקינג משלו, אחד מהם יכול להיות מעל ה-div של התוכן והשני יכול להיות מתחת ל-div של התוכן. ראו את הדוגמה המתוקנת, שפועלת ב-Chrome 21 וב-22:

https://codepen.io/wiltzius/pen/vhFzG

הקרדיט על יצירת הדוגמה הזו מגיע ל-hixie הבלתי נשכח.

Chrome הוא הדפדפן הראשון למחשב שבו רכיבים עם position:fixed יוצרים הקשרים משלהם של סטאקינג. התקן הרלוונטי הוא מפרט z-index של CSS (ראו למשל https://www.w3.org/TR/CSS21/zindex.html). עדיין אין הסכמה לגבי הטיפול בהבדל בין דפדפנים לנייד ולמחשב, אבל בגלל הבלבול שנוצר כתוצאה משתי התנהגויות שונות בנייד ובמחשב, ב-Chrome בחרו לעבור להתנהגות אחת בשתי הפלטפורמות בינתיים.

עדכון מ-1 באוקטובר 2012: בגרסה המקורית של המאמר נכתב שהמפרט z-index של CSS כבר השתנה כדי לשקף את ההתנהגות החדשה של רכיבים עם position: fixed. זה לא נכון. הנושא הזה נדון ברשימת www-style, אבל עדיין לא בוצע שינוי במפרט.