web-dev-qa-db-fra.com

css z-index perdu après la transformation du webkit translate3d

J'ai deux éléments div absolument positionnés qui se chevauchent. Les deux ont défini les valeurs z-index via css. J'utilise la transformation translate3d Webkit pour animer ces éléments hors de l'écran, puis de nouveau à l'écran. Après la transformation, les éléments ne respectent plus leurs valeurs définies z-index.

Quelqu'un peut-il expliquer ce qu'il advient de l'ordre z-index/stack-of des éléments div une fois que j'effectue une transformation de kit Web sur eux? Et expliquer ce que je peux faire pour conserver l’ordre de pile des éléments div?

Voici quelques informations supplémentaires sur la façon dont je réalise la transformation.

Avant la transformation, chaque élément obtient ces deux valeurs de transition webkit définies via css (jQuery est utilisé pour effectuer les appels de fonction .css():

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

L'élément est ensuite animé à l'aide de translate3d -webkit-transform:

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

Par ailleurs, j'ai essayé de définir le troisième paramètre de translate3d Sur plusieurs valeurs différentes pour tenter de répliquer l'ordre de pile dans l'espace 3D, mais sans succès.

De plus, les navigateurs iPhone/iPad et Android sont les navigateurs cibles sur lesquels ce code doit être exécuté. Tous les deux prennent en charge les transitions Webkit.

95
Rafe

Cela pourrait être lié à: https://bugs.webkit.org/show_bug.cgi?id=61824

En gros, lorsque vous appliquez une transformation 3D sur l'axe z, l'index z ne peut plus être pris en compte (vous êtes maintenant dans un plan de rendu en 3 dimensions, utilisez des valeurs z différentes). Si vous souhaitez revenir au rendu 2D pour les éléments enfants, utilisez transform-style: flat;.

49
samy-delux

Ceci est très certainement lié au bogue noté par samy-delux. Cela ne devrait affecter que les éléments qui sont positionnés comme absolus ou relatifs. Afin de remédier à ce problème, vous pouvez appliquer l'instruction css suivante à chaque élément positionné de cette manière et générant des problèmes:

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

Cela appliquera la transformation à l'élément sans effectuer réellement de transformation, mais en affectant l'ordre de son rendu afin qu'il soit au-dessus de l'élément à l'origine du problème.

43
divThis

Un peu tard pour cela, mais essayez de mettre les éléments qui ont perdu leur Z-index en plaçant ce qui suit, j'ai eu un problème en faisant quelques trucs de parallaxe récemment et cela a aidé massivement.

transform-style: preserve-3d;

Cela évite de mettre

transform: translate3d(0,0,0);

Sur d'autres éléments qui sollicitent davantage le GPU

12
RustyCollins

En attente de voir l'exemple

Avez-vous essayé de faire une échelle de transformation (1)? Je me souviens d'avoir eu un problème similaire, et je devais réorganiser l'ordre HTML des éléments et utiliser une transformation dont je n'avais pas besoin simplement parce que l'indice z de l'utilisation de la transformation changeait.

Si je ne me trompe pas, chaque fois que vous utilisez une transformation, celle-ci devient l'indice z le plus élevé disponible, et il est commandé par l'élément le plus proche de HTML situé au début de la balise. Donc de haut en bas.

J'espère que cette aide

7
Littlemad

z-index Fonctionnera contre les div transformées en 3D si vous appelez l'élément empilable avec -webkit-transform: translateZ(0px);

Extrait sur codepen -> http://codepen.io/mrmoje/pen/yLIul

Dans l'exemple, les boutons stack up Et stack down Lèvent et abaissent l'index z du pied de page (+/- 1) par rapport à l'élément pivoté (un img dans ce cas).

5
moje

Je n'ai pas été capable de reproduire le problème que vous décrivez ici. Indépendamment de ce que je fais, la valeur de z-index est conservée pendant toutes les transformations. Je teste avec Chrome (Google Chrome).

Le troisième argument de la fonction translate3d manipule l'axe z de l'élément. Le concept est similaire à l'indice z, mais pas exactement identique à celui-ci ... Les éléments d'axe z inférieur se trouvent sous les éléments de valeur supérieure.

Je sais que vous avez essayé d'utiliser les valeurs du troisième argument pour correspondre à votre index z souhaité, mais le problème est que l'axe z ne semble pas changer pendant l'animation CSS3. Dans l'exemple suivant, l'élément survolé devrait être en haut, mais #element_a reste en haut.

Si j'ajoute un z-index à la fois au sélecteur normal et au sélecteur: hover, il semble fonctionner et permet à l'élément survolé d'être tout en haut.

Bien que ce ne soit pas exactement ce que vous recherchiez, ce comportement fournit une solution. Il vous suffit d'utiliser translate3d et z-index pour définir l'ordre du rendu initial.

<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>
3
user166560

Une autre solution consiste à créer un élément parent et à appliquer toutes les autres transitions qui lui sont associées:

# 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

0
Rust