Menu

z-index in CSS: ordine di sovrapposizione e stacking context

z-index decide quale elemento sovrapposto viene disegnato sopra. Impara su quali elementi funziona, come gli stacking context raggruppano gli elementi così che uno z-index di 9999 possa comunque perdere, cosa crea uno stacking context e come sistemare uno z-index che non funziona.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Cosa fa z-index

Quando gli elementi si sovrappongono, z-index decide quale viene disegnato davanti. Vince il numero più alto. Funziona sugli elementi posizionati (qualsiasi position tranne static) e sugli elementi flex e grid:

Senza z-index, gli elementi che vengono dopo nell'HTML sono disegnati sopra quelli precedenti, quindi C coprirebbe B e B coprirebbe A. I valori di z-index invertono questo ordine: A sta davanti, poi C, poi B.

I valori

ValoreSignificato
auto (predefinito)Impilato al livello 0 con i suoi fratelli, e non crea uno stacking context
0Livello 0, ma crea uno stacking context
Intero positivoDavanti ai valori più bassi
Intero negativoDietro il livello 0, e dietro il contenuto del genitore se è il genitore a formare lo stacking context

Sono validi solo i numeri interi: z-index: 1.5 viene ignorato.

Perché uno z-index di 9999 può perdere: gli stacking context

I valori di z-index non vengono confrontati su tutta la pagina. Gli elementi sono raggruppati in stacking context, e uno z-index ordina solo gli elementi all'interno dello stesso contesto. Il contesto viene poi posizionato come un unico livello, usando lo z-index dell'elemento che l'ha creato.

Qui sotto, il menu a tendina blu ha z-index: 9999, ma vive dentro un header con z-index: 1. Il banner verde, fratello di quell'header, ha z-index: 2. L'intero livello dell'header, menu incluso, sta sotto il banner:

Premi il pulsante. Con z-index: auto l'header non forma più uno stacking context, quindi il 9999 del menu viene confrontato direttamente con il 2 del banner, e il menu passa in primo piano. Alzare il menu a 99999 non sarebbe mai servito.

Cosa crea uno stacking context

Una qualsiasi di queste proprietà trasforma un elemento in un proprio stacking context, intrappolando lo z-index di tutto ciò che contiene:

ProprietàCondizione
position: relative o absoluteCon uno z-index diverso da auto
position: fixed o stickySempre
Elemento flex o gridCon uno z-index diverso da auto
opacityMinore di 1
transform, scale, rotate, translateQualsiasi valore diverso da none
filter, backdrop-filterQualsiasi valore diverso da none
isolationisolate
mix-blend-modeQualsiasi valore diverso da normal
will-changeSe nomina una delle proprietà qui sopra
containlayout o paint (e strict, content)

Quelle che sorprendono sono opacity e transform: aggiungere una dissolvenza o un'animazione al passaggio del mouse su un genitore può mandare all'improvviso il suo menu a tendina dietro la sezione successiva.

Lo z-index: 10 del tooltip dovrebbe metterlo sopra la colonna successiva. Ma opacity: 0.99 fa della prima colonna uno stacking context con z-index auto (livello 0), e la seconda colonna viene dopo nell'HTML allo stesso livello, quindi viene disegnata sopra l'intera prima colonna, tooltip incluso. Cancella la riga di opacity e il tooltip torna davanti.

z-index negativo

Uno z-index negativo mette un elemento dietro i suoi fratelli. Se il genitore non forma uno stacking context, può finire persino dietro lo sfondo del genitore, una sorpresa frequente. isolation: isolate sul genitore crea un contesto senza nessun altro effetto visivo e tiene al suo interno il figlio negativo:

Senza isolation, la cornice ambra scivola dietro lo sfondo grigio del pulsante stesso, quindi se ne vede solo il bordo. Con isolation: isolate, la cornice resta dentro lo stacking context del pulsante: sopra il suo sfondo, sotto il suo testo.

Una scala di z-index

Scegli pochi livelli con un nome per tutto il sito invece di alzare i numeri all'infinito:

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

La maggior parte dei bug di sovrapposizione sono bug di stacking context, non di numeri, quindi una piccola scala più isolation: isolate sui componenti che usano z-index al loro interno risolve molto. z-index ha bisogno del posizionamento per funzionare; la pagina su position lo spiega.

Errori comuni

  • z-index su un elemento static. Aggiungi position: relative (o rendilo un elemento flex o grid).
  • Salire fino a 9999. Se un genitore forma uno stacking context sotto il rivale, nessun valore del figlio può vincere. Cerca invece il contesto.
  • Un nuovo opacity, transform o filter su un genitore che all'improvviso intrappola il suo menu a tendina.
  • Valori decimali. z-index: 1.5 non è valido.
  • Aspettarsi che z-index: 0 e auto si comportino allo stesso modo. 0 crea uno stacking context; auto no.
  • Modali dentro componenti molto annidati. Mettili verso la fine di <body> (oppure usa il top layer dell'elemento <dialog>), così nessun contesto antenato può intrappolarli.

Domande frequenti

Cosa fa z-index?

Imposta l'ordine di sovrapposizione degli elementi che si sovrappongono: un valore più alto viene disegnato davanti a uno più basso all'interno dello stesso stacking context. Il valore predefinito è auto, e i valori sono numeri interi, compresi quelli negativi.

Perché il mio z-index non funziona?

O l'elemento non è posizionato (z-index ha bisogno di un position diverso da static, oppure di un figlio flex o grid), oppure si trova dentro un genitore che forma uno stacking context con un ordine più basso. Un figlio non può mai salire sopra un elemento sotto il quale è posto il suo stacking context, qualunque sia il suo z-index.

Cos'è uno stacking context?

Un gruppo di elementi che vengono impilati insieme come un unico livello. Al suo interno, i figli sono ordinati in base al loro z-index; all'esterno, l'intero gruppo viene posizionato in base allo z-index dell'elemento che l'ha creato.

Cosa crea uno stacking context?

Tra gli altri: l'elemento radice, un elemento posizionato con uno z-index diverso da auto, position: fixed o sticky, un figlio flex o grid con uno z-index, opacity minore di 1, transform, filter, isolation: isolate e will-change su quelle proprietà.

z-index funziona senza position?

Non sui normali elementi block o inline: position: static lo ignora. Funziona invece sugli elementi flex e grid senza alcun position.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA