Perché lo stile z-index non si applica all’elemento ?

Lo stile z-index ti consente di controllare in quali caselle di ordine vengono dipinte. Ad esempio, puoi fare in modo che un elemento figlio venga dipinto sotto l’elemento principale:

 #parent { background: rgba(33, 33, 33, 0.7); } #child { width: 100px; height: 100px; background: yellow; position: relative; z-index: -1; } 
 

Tuttavia, quando l’elemento genitore è il tag , questo non si comporta più come previsto:

 body { background: rgba(33, 33, 33, 0.7); } #child { width: 100px; height: 100px; background: yellow; position: relative; z-index: -1; } 
  

La specifica CSS §9.9.1 (enfatizza il mio):

L’elemento radice costituisce il contesto di stacking della radice. Altri contesti di impilamento sono generati da qualsiasi elemento posizionato (inclusi gli elementi relativamente posizionati) con un valore calcolato di ‘z-index’ diverso da ‘auto’. I contesti di impilamento non sono necessariamente correlati ai blocchi di contenimento. Nei livelli futuri del CSS, altre proprietà possono introdurre contesti di impilamento, ad esempio ” opacità ” [CSS3COLOR] .

All’interno di ogni contesto di impilamento, i seguenti livelli sono dipinti in ordine “back-to-front”:

  1. lo sfondo e i bordi dell’elemento che formano il contesto di impilamento .
  2. il bambino impila i contesti con livelli di pila negativi (prima i più negativi).
  3. i discendenti in-flow, non in linea e non posizionati.
  4. i galleggianti non posizionati.
  5. i discendenti in-flow, a livello di linea e non posizionati, incluse le tabelle in linea e i blocchi in linea.
  6. il bambino impila i contesti con il livello di stack 0 e i discendenti posizionati con il livello di stack 0.
  7. il bambino impila i contesti con livelli di pila positivi (prima i meno positivi).

Se fosse l’elemento radice, allora questo comportamento avrebbe senso, poiché ciò significherebbe che l’elemento viene sempre dipinto per primo, indipendentemente da cosa.

Tuttavia, in un documento HTML, è l’elemento principale. Detto questo, perché non possiamo posizionare un elemento in con lo stile z-index ?


(Questa domanda è stata motivata da una domanda simile sul sito di Russian Stack Overflow .)

Il problema qui è che se l’elemento html non ha uno sfondo specificato, il canvas adotta lo sfondo dell’elemento body e viene dipinto per primo. Il CSS 2.1 dice :

Per i documenti il ​​cui elemento radice è un elemento HTML “HTML” o un elemento “html” XHTML che ha valori calcolati di “transparent” per “background-color” e “none” per “background-image”, i programmi utente devono invece utilizzare il valore calcolato delle proprietà di sfondo dal primo elemento HTML “BODY” dell’elemento o bambino “body” dell’elemento XHTML quando si dipingono gli sfondi per il canvas e non si deve dipingere uno sfondo per quell’elemento secondario.

Guarda cosa succede quando l’elemento html ha uno sfondo:

 html { background-color: white; } body { background: rgba(33, 33, 33, 0.7); } #child { width: 100px; height: 100px; background: yellow; position: relative; z-index: -1; } 
  

Il posizionamento predefinito del tag è static . E per definizione il posizionamento statico significa ignorare tutte le istruzioni di posizionamento .

In altre parole perché la proprietà z-index non si applica agli elementi che hanno la position:static , non si applica al body in quanto la sua posizione predefinita è static

Ecco una buona discussione sul perché z-index non funziona sulla position:static

Aggiornamento: allora perché non funziona con il corpo {position: relative}?

Perché il body diventa un contesto impilabile . Ora con z-index, un elemento può solo andare avanti o indietro rispetto ai suoi siblings ma mai dietro il suo genitore. Poiché il body è un elemento parent , l’impostazione di z-index negativo sul suo figlio non la porta dietro al corpo.

Difficile trovare documentazione ufficiale o addirittura autorevole su questo argomento, probabilmente perché non è uno scenario comune nella vita reale, ma il problema è stato discusso in precedenza da Ian Hickson e Tantek Celik , i redattori della Specifica CSS .

Di seguito sono riportate alcune parti di una discussione da una mailing list W3C in cui gli autori delle spec discussioni discutono sul comportamento di z-index in relazione all’elemento body .

L’essenza della discussione è questa:

  • Il browser ha ragione di ignorare z-index su elementi non posizionati (come body ), perché z-index applica solo agli elementi posizionati

  • L’indicizzazione z di un elemento è relativa solo agli elementi di pari livello e non agli elementi principali, a causa della creazione di contesti di impilamento

    … una casella figlio non può eludere l’ordine z del suo genitore. può posizionarsi dietro o davanti a uno dei suoi fratelli, ma non può posizionarsi dietro la sua casella genitore. può posizionarsi in modo tale che sia il primo figlio reso prima di ogni altro bambino ….

  • C’è anche una nota interessante sul comportamento di z-index con position: fixed sull’elemento body , ma non sembra che sia stato implementato .


Tantek Celik:

Ho una domanda riguardante la proprietà z-index : Perché posso ancora vedere elementi che ho messo dietro l’elemento BODY (vedi esempio sotto)?

Perché il tuo browser ha un bug o non supporta z-index .

Oppure il browser non ha un bug e sta correttamente ignorando z-index su elementi non posizionati.

Questo è un test che mostra un testo che non dovrebbe essere visibile poiché si trova dietro l’elemento body (la proprietà “z-index” è uguale a “-1”).

Nell’esempio fornito, entrambi gli elementi che hanno uno z-index non hanno la loro proprietà position impostata, e poiché in base a:

http://www.w3.org/TR/REC-CSS2/visuren.html#z-index

la proprietà z-index “Si applica a: elementi posizionati”, le impostazioni sulla proprietà z-index vengono ignorate.

Tantek

risposta dello sceneggiatore :

Ciao,

(Tantek: sono d’accordo con te che la specifica dice che z-index è solo per elementi posizionati , ma come dice Ian, non vedo perché non possa essere applicato per scatole statiche che si sovrappongono a causa di margini negativi).

guarda il seguente markup:

ciao !!

mondo !!

P è un figlio di BODY, e secondo le specifiche CSS2 (la mia lettura, comunque 🙂 z-indexing di un elemento è relativo solo a elementi di pari livello, e non a elementi padre. questo ha a che fare con la creazione di un contesto z-index.

quindi la scatola per “ciao !!” apparirebbe dietro la scatola per “mondo !!” ma NON dietro la scatola di BODY perché BODY contiene entrambe le caselle di elementi P.

!!! per favore correggi se ho sbagliato su questo, perché se lo sono, devo rifare il mio renderer in modo che non rispetti i confini gerarchici, che NON è una situazione felice. !!!

l’intento originale di questo thread (la domanda) può essere raggiunto facendo dello z-index=-1 una position: fixed box (anche se le proprietà di posizionamento sarebbero complesse). Ciò funzionerebbe perché le caselle fisse si scontrassero dalla gerarchia dove vengono trovati e levitati al riquadro della finestra, diventando essenzialmente un fratello della scatola BODY.

– ranjit

scrittore di spec:

per favore,

scusate il mio uso di termini specifici di implementazione.

hai ragione riguardo l’ipotesi HTML. ma il mio punto rimane valido, anche se osserviamo la gerarchia della struttura del documento / box indipendentemente dal markup.

attualmente, nella mia implementazione, la seguente regola implicita è dettata dalla struttura gerarchica delle caselle generate dall’analisi di una struttura gerarchica del documento (XML, HTML, …)

REGOLA: una casella figlio non può eludere l’ordine z del suo genitore. può posizionarsi dietro o davanti a uno dei suoi fratelli, ma non può posizionarsi dietro la sua casella genitore. può posizionarsi in modo tale che sia il primo figlio reso prima di ogni altro bambino, ….

Vedo questa regola implicita anche nella specifica CSS2, nella sezione in cui si parla di contesti di ordine z e così via.

come vedo, i valori di ordine z per le caselle CHILD sono validi all’interno del contesto di ordine z principale. questo può essere illustrato con caselle posizionate in modo assoluto contenenti caselle posizionate in modo assoluto in cui le caselle assolute di un bambino hanno un ordinamento z che non può violare l’ordine z delle caselle assolute padre.

ancora una volta, lasciami dire: se ho frainteso qualcosa nelle specifiche, fammi sapere, perché se la regola precedente non è valida, allora mi sembra che la nozione di gerarchia non sia preservata per le caselle non fisse.

Saluti,

– ranjit

http://lists.w3.org/Archives/Public/www-style/1999Aug/0131.html

Bene, non c’è molta documentazione su questo.

Ma il tag non può avere alcun fratello, quindi perché mai sarebbe necessario cambiare il suo z-index?

È considerato anche un elemento “posizionato”?

Puoi giocare con i suoi elementi figlio z-index come desideri e ottenere i risultati desiderati in qualsiasi situazione, non c’è bisogno di complicare troppo l’html con gli stili css senza alcuna ragione

Il tag è impostato in modo predefinito per rimanere nella parte inferiore della pila. Semplicemente non può essere impostato in quanto sarà sempre il valore più basso ansible.

Fonte: forum di Adobe