Menu

z-index ב-CSS: סדר ערימה ו-stacking context

z-index קובע איזה מבין אלמנטים חופפים מצויר למעלה. למדו על אילו אלמנטים הוא עובד, איך stacking context מקבץ אלמנטים כך ש-z-index של 9999 עדיין יכול להפסיד, מה יוצר stacking context, ואיך לתקן z-index שלא עובד.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

מה z-index עושה

כשאלמנטים חופפים, z-index קובע איזה מהם מצויר מלפנים. המספר הגבוה יותר מנצח. הוא עובד על אלמנטים ממוקמים (כל position חוץ מ-static) ועל פריטי flex ו-grid:

בלי z-index, אלמנטים שמופיעים מאוחר יותר ב-HTML מצוירים מעל אלה שלפניהם, כך ש-C היה מכסה את B ו-B היה מכסה את A. ערכי ה-z-index הופכים את זה: A מלפנים, אחריו C, ואז B.

הערכים

ערךמשמעות
auto (ברירת מחדל)נערם ברמה 0 יחד עם האחים שלו, ולא יוצר stacking context
0רמה 0, אבל יוצר stacking context
מספר שלם חיובימול ערכים נמוכים יותר
מספר שלם שלילימאחורי רמה 0, ומאחורי התוכן של ההורה אם ההורה יוצר את ה-stacking context

רק מספרים שלמים תקינים: z-index: 1.5 נזרק.

למה z-index 9999 יכול להפסיד: stacking context

ערכי z-index לא מושווים על פני הדף כולו. האלמנטים מקובצים ל-stacking contexts, ו-z-index מסדר רק אלמנטים שנמצאים באותו context. אחר כך ה-context עצמו ממוקם כשכבה אחת, לפי ה-z-index של האלמנט שיצר אותו.

בדוגמה למטה, לתפריט הנפתח הכחול יש z-index: 9999, אבל הוא חי בתוך header עם z-index: 1. לבאנר הירוק, אח של אותו header, יש z-index: 2. כל שכבת ה-header, כולל התפריט הנפתח, נמצאת מתחת לבאנר:

לחצו על הכפתור. עם z-index: auto ה-header כבר לא יוצר stacking context, ולכן ה-9999 של התפריט הנפתח מושווה ישירות ל-2 של הבאנר, והתפריט עובר קדימה. להעלות את התפריט ל-99999 לא היה עוזר אף פעם.

מה יוצר stacking context

כל אחד מאלה הופך אלמנט ל-stacking context משלו, ולוכד את ה-z-index של כל מה שבתוכו:

מאפייןתנאי
position: relative או absoluteעם z-index שהוא לא auto
position: fixed או stickyתמיד
פריט flex או gridעם z-index שהוא לא auto
opacityמתחת ל-1
transform, scale, rotate, translateכל ערך שהוא לא none
filter, backdrop-filterכל ערך שהוא לא none
isolationisolate
mix-blend-modeכל ערך שהוא לא normal
will-changeשמציין אחד מהמאפיינים שלמעלה
containlayout או paint (וגם strict, content)

המפתיעים הם opacity ו-transform: הוספה של fade או של אנימציית hover להורה יכולה פתאום לשים את התפריט הנפתח שלו מאחורי האזור הבא.

ה-z-index: 10 של ה-tooltip אמור לשים אותו מעל העמודה הבאה. אבל opacity: 0.99 הופך את העמודה הראשונה ל-stacking context עם z-index auto (רמה 0), והעמודה השנייה מופיעה מאוחר יותר ב-HTML באותה רמה, ולכן היא מצוירת מעל כל העמודה הראשונה, כולל ה-tooltip. מחקו את השורה של opacity וה-tooltip חוזר קדימה.

z-index שלילי

z-index שלילי שם אלמנט מאחורי האחים שלו. אם ההורה לא יוצר stacking context, הוא יכול אפילו לרדת מאחורי הרקע של ההורה, וזו הפתעה נפוצה. isolation: isolate על ההורה יוצר context בלי שום אפקט חזותי אחר ומשאיר את הילד השלילי בתוכו:

בלי isolation, המסגרת הכתומה יורדת מאחורי הרקע האפור של הכפתור עצמו, ולכן רק הקצה שלה נראה. עם isolation: isolate, המסגרת נשארת בתוך ה-stacking context של הכפתור: מעל הרקע שלו, מתחת לטקסט שלו.

סולם z-index

בחרו כמה שכבות עם שמות לכל האתר במקום להעלות מספרים שוב ושוב:

:root {
  --z-dropdown: 10;
  --z-sticky: 20;
  --z-overlay: 30;
  --z-modal: 40;
  --z-toast: 50;
}
.modal { position: fixed; z-index: var(--z-modal); }

רוב הבאגים של שכבות הם באגים של stacking context, לא באגים של מספרים, ולכן סולם קטן יחד עם isolation: isolate על רכיבים שמשתמשים ב-z-index בפנים עושה הרבה. z-index צריך מיקום כדי לעבוד; הדף על position מסביר את זה.

טעויות נפוצות

  • z-index על אלמנט static. הוסיפו position: relative (או הפכו אותו לפריט flex או grid).
  • הסלמה ל-9999. אם הורה יוצר stacking context מתחת למתחרה, שום ערך של ילד לא יכול לנצח. חפשו את ה-context במקום זה.
  • opacity, transform או filter חדש על הורה שפתאום לוכד את התפריט הנפתח שלו.
  • ערכים עשרוניים. z-index: 1.5 לא תקין.
  • לצפות ש-z-index: 0 ו-auto יתנהגו אותו דבר. 0 יוצר stacking context; auto לא.
  • חלונות modal בתוך רכיבים מקוננים עמוק. רנדרו אותם קרוב לסוף של <body> (או השתמשו ב-top layer של האלמנט <dialog>), כך שאף context של אב לא יוכל ללכוד אותם.

שאלות נפוצות

מה z-index עושה?

הוא קובע את סדר הערימה של אלמנטים חופפים: ערך גבוה יותר מצויר מול ערך נמוך יותר באותו stacking context. ברירת המחדל היא auto, והערכים הם מספרים שלמים, כולל שליליים.

למה ה-z-index שלי לא עובד?

או שהאלמנט לא ממוקם (z-index צריך position שהוא לא static, או ילד של flex או grid), או שהוא יושב בתוך הורה שיוצר stacking context עם סדר נמוך יותר. ילד אף פעם לא יכול לעלות מעל אלמנט שה-stacking context שלו ממוקם מתחתיו, לא משנה מה ה-z-index שלו עצמו.

מה זה stacking context?

קבוצה של אלמנטים שנערמים יחד כשכבה אחת. בתוכה, הילדים מסודרים לפי ה-z-index שלהם; מחוץ לה, כל הקבוצה ממוקמת לפי ה-z-index של האלמנט שיצר אותה.

מה יוצר stacking context?

בין השאר: אלמנט השורש, אלמנט ממוקם עם z-index שהוא לא auto, position: fixed או sticky, ילד של flex או grid עם z-index, opacity מתחת ל-1, transform, filter, isolation: isolate, ו-will-change על המאפיינים האלה.

האם z-index עובד בלי position?

לא על אלמנטים רגילים מסוג block או inline: position: static מתעלם ממנו. הוא כן עובד על פריטי flex ופריטי grid בלי שום position.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל