מה 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 |
isolation | isolate |
mix-blend-mode | כל ערך שהוא לא normal |
will-change | שמציין אחד מהמאפיינים שלמעלה |
contain | layout או 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.