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

Tom Wiltzius
Tom Wiltzius

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

סידור בערימה של מה?

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

סקירה כללית לגבי הקשרים של סידור בערימה זמינה במאמר הזה בנושא MDN.

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

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

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

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

פרטי השינוי

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

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

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

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

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

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

בדיקות ועתיד

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

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

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

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

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

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

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

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

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