css z-index perso dopo la trasformazione di webkit translate3d


98

Ho due elementi div posizionati in modo assoluto che si sovrappongono. Entrambi hanno impostato i valori di z-index tramite css. Uso la translate3dtrasformazione del webkit per animare questi elementi fuori dallo schermo e poi di nuovo sullo schermo. Dopo la trasformazione, gli elementi non rispettano più i z-indexvalori impostati .

Qualcuno può spiegare cosa succede all'ordine z-index / stack degli elementi div una volta che ho trasformato un webkit su di essi? E spiegare cosa posso fare per mantenere l'ordine di stack degli elementi div?

Ecco qualche informazione in più su come sto facendo la trasformazione.

Prima della trasformazione, ogni elemento ottiene questi due valori di transizione del webkit impostati tramite css (sto usando jQuery per eseguire le .css()chiamate di funzione:

element.css({ '-webkit-transition-duration': duration + 's' });
element.css({ '-webkit-transition-property': '-webkit-transform' });

L'elemento viene quindi animato utilizzando translate3d -webkit-transform:

element.css({ '-webkit-transform': 'translate3d(' + hwDelta + 'px, 0, -1px)' });

A proposito, ho provato a impostare il 3 ° parametro su translate3ddiversi valori per provare a replicare l'ordine dello stack nello spazio 3d, ma senza fortuna.

Inoltre, i browser iPhone / iPad e Android sono il mio browser di destinazione su cui deve essere eseguito questo codice. Entrambi supportano le transizioni webkit.


Puoi pubblicare un link per vedere l'esempio?
Littlemad

1
Ho incontrato lo stesso problema. Ho un tag <iframe> con lo stile dell'elemento interno "-webkit-transform: translate3d (0,0,0)" per forzare l'accelerazione 3d. Si scopre che il frame esterno con uno z-index più alto è sempre nascosto dall'elemento iframe interno. Solo visivamente nascosto, posso "fare clic" sull'elemento esterno invisibile. Questo accade solo in Mobile Safari.
Morgan Cheng

Ho passato 10 ore a capire che era quello che stava facendo il mio codice non funzionante. Ugh
Dikeneko

Risposte:


52

Questo potrebbe essere correlato a: https://bugs.webkit.org/show_bug.cgi?id=61824

Fondamentalmente quando applichi una trasformazione 3D sull'asse z, lo z-index non può più essere considerato (ora ti trovi in ​​un piano di rendering tridimensionale, usa valori z diversi). Se vuoi tornare al rendering 2D per gli elementi figli, usa transform-style: flat;.


13
Fondamentalmente quando applichi una trasformazione 3D sull'asse z, lo z-index non può più essere considerato (ora ti trovi in ​​un piano di rendering tridimensionale, usa valori z diversi). Se vuoi tornare al rendering 2D per gli elementi figli, usa transform-style: flat;.
samy-delux

2
Quindi in modalità "Preserva 3d" dobbiamo usare l'asse z di trasformazione per impostare l'ordine, e in modalità piatta dovremmo usare z-index. Il bug è che z-index su Safari è rotto in combinazione con trasformazioni accelerate HW.
Steven Lu

1
non funziona. Funziona solo se rimuovo gli stili animati per classe.
fdrv

44

Questo è sicuramente correlato al bug notato da samy-delux. Ciò dovrebbe interessare solo gli elementi posizionati come assoluti o relativi. Per rimediare al problema, puoi applicare la seguente istruzione css a ogni elemento che è posizionato in questo modo e sta causando problemi:

-webkit-transform: translate3d(0,0,0);

Ciò applicherà la trasformazione all'elemento senza effettivamente eseguire una trasformazione, ma influirà sul suo ordine di rendering in modo che si trovi sopra l'elemento che causa il problema.


Utilizzando Chrome (35.0.1916.114 m), ho scoperto che se non avevo questa regola, dopo che l'elemento è stato capovolto [transform: rotateY (180deg)], i gestori di clic jQuery non funzionavano più per quell'elemento. Inoltre, dopo un capovolgimento, ci sono problemi con gli artefatti lasciati sullo schermo e specialmente se la loro opacità è stata modificata, a meno che non sia presente translate3d! Questo articolo ha aiutato sitepoint.com/fix-chrome-animation-flash-bug
Philip Murphy,

2
Questo ha appena risolto un problema molto complicato per me riguardante due elementi fissi, uno contenente un elemento trasformato in 3D. L'elemento trasformato in 3D fondamentalmente trabocca e si posiziona sopra l'altro elemento fino a quando non viene applicata la correzione di cui sopra.
Collin James

1
non funziona. Funziona solo se rimuovo gli stili animati per classe.
fdrv

12

Un po 'in ritardo per questo, ma prova a inserire gli elementi che hanno perso il loro Z-index posizionando quanto segue, ho avuto un problema quando ho fatto alcune cose di parallasse di recente e questo ha aiutato enormemente.

transform-style: preserve-3d;

Ciò consente di risparmiare la messa

transform: translate3d(0,0,0);

Su altri elementi che mettono a dura prova la GPU


1
Quando i tuoi elementi sono 3d, non mi aspetto che una trasformazione metta a dura prova la GPU. I calcoli devono essere effettuati comunque. Su cosa ti stai basando?
Micros

7

In attesa di vedere l'esempio

Hai provato a fare una scala di trasformazione (1)? Ricordo di avere avuto un problema simile, e ho dovuto riorganizzare l'ordine html degli elementi e utilizzare una trasformazione che non mi serviva solo perché lo z-index dell'uso della trasformazione è cambiato.

Se non sono in errore, ogni volta che usi una trasformazione, diventa il più alto z-index disponibile, ed è ordinato dall'elemento html più vicino all'inizio del tag. Quindi dall'alto al basso.

Spero che questo aiuto


6

z-index funzionerà con div trasformati in 3D se definisci lo stile dell'elemento impilabile con -webkit-transform: translateZ(0px);

Snippet su codepen -> http://codepen.io/mrmoje/pen/yLIul

Nell'esempio, i pulsanti stack upe stack downalza e abbassa lo z-index del piè di pagina (+/- 1) rispetto all'elemento ruotato (in questo caso un'immagine).


lo stack up non può essere cliccato di nuovo
clevertension

Ehi @ Moje, mi chiedo anche questo problema. Non è ancora possibile fare nuovamente clic sulla pila.
alchuang

Perché non ho pensato di aggiungere uno z-index negativo all'elemento tradotto? Grazie
Will

3

Non sono stato in grado di riprodurre il problema che descrivi qui. Indipendentemente da ciò che faccio, il valore z-index viene mantenuto durante tutte le trasformazioni. Sto testando utilizzando Chromium (Google Chrome).

Il terzo argomento della funzione translate3d manipola l'asse z dell'elemento. Il concetto è simile, ma non esattamente lo stesso, allo z-index ... Gli elementi con un asse z inferiore sono sotto gli elementi con un valore più alto.

So che hai provato i valori del terzo argomento per abbinare il tuo z-index previsto, ma il problema è che l'asse z non sembra cambiare durante l'animazione CSS3. Nell'esempio seguente, l'elemento al passaggio del mouse dovrebbe essere in alto, ma #element_a rimane in primo piano.

Se aggiungo uno z-index sia al selettore normale che al selettore: hover, sembra funzionare e consentire all'elemento al passaggio del mouse di essere il più in alto.

Sebbene non sia esattamente quello che stavi cercando, questo comportamento fornisce una soluzione. Hai solo bisogno di usare translate3d e z-index per impostare l'ordine per il rendering iniziale.

<style>
    div {
        width: 300px;
        height: 150px;
        background-color: white;
        border: 5px outset gray;
        float: left;
        margin: 20px;
        -webkit-transition: 2s;
    }

    #element_a {
        -webkit-transform: translate3d(0, 0, 50px);
    }
    #element_b {
        -webkit-transform: translate3d(0, 0, 100px);
    }

    #element_a:hover {
        -webkit-transform: translate3d(100px, 0, 60px);
    }

    #element_b:hover {
        -webkit-transform: translate3d(-100px, 0, -60px);
    }
</style>
<body>
    <div id="element_a">
        <img src="http://www.google.com/intl/en_com/images/srpr/logo3w.png">
    </div>
    <div id="element_b">
        <img src="http://www.google.com/intl/en_com/images/srpr/logo3w.png">
    </div>
</body>

2
Questo ha funzionato per me - grazie! Ho aggiunto quanto segue all'elemento che voglio essere 'in primo piano': -webkit-transform: translate3d (0, 0, 1px);
Sam Dutton

0

Un altro modo per aggirare questo è che puoi creare un elemento genitore e applicare tutte le altre transizioni ad esso correlate:

# Apply transitions to a parent div
<div>
  # This image z-index -1 
  <img src="foo"/>

  # This image z-index -3
  <img src="bar"/>

  #This image z-index -2
  <img src="gg"/>
</div>

JsFiddle

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.