css z-index utracony po przekształceniu webkita translate3d


98

Mam dwa absolutnie ustawione elementy div, które się nakładają. Oba mają ustawione wartości indeksu z za pośrednictwem css. Używam translate3dWebKit przekształcić animowanie tych elementów z ekranu, a następnie z powrotem na ekran. Po transformacji elementy nie przestrzegają już ustalonych z-indexwartości.

Czy ktoś może wyjaśnić, co dzieje się z kolejnością Z-index / stack elementów div, gdy wykonam na nich transformację webkita? I wyjaśnij, co mogę zrobić, aby zachować kolejność elementów div na stosie?

Oto więcej informacji o tym, jak dokonuję transformacji.

Przed transformacją każdy element otrzymuje te dwie wartości przejścia webkit ustawiane za pośrednictwem css (używam jQuery do wykonywania .css()wywołań funkcji:

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

Element jest następnie animowany przy użyciu translate3d -webkit-transform:

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

Przy okazji, próbowałem ustawić trzeci parametr translate3dna kilka różnych wartości, aby spróbować odtworzyć kolejność stosu w przestrzeni 3D, ale bez powodzenia.

Ponadto przeglądarki iPhone / iPad i Android są moją docelową przeglądarką, na której ten kod musi działać. Oba obsługują przejścia z webkitami.


Czy możesz opublikować link, aby zobaczyć przykład?
— Littlemad

1
Spotkałem ten sam problem. Mam jeden tag <iframe> ze stylem elementu wewnętrznego „-webkit-transform: translate3d (0,0,0)”, aby wymusić przyspieszenie 3D. Okazuje się, że zewnętrzna ramka z wyższym indeksem Z jest zawsze ukryta przez wewnętrzny element iframe. Po prostu wizualnie ukryty, mogę „kliknąć” niewidoczny element zewnętrzny. Dzieje się tak tylko w Mobile Safari.
— Morgan Cheng,

Spędziłem 10 godzin, zastanawiając się, co powoduje, że mój kod nie działa. Ugh
— Dikeneko

Odpowiedzi:


52

Może to być związane z: https://bugs.webkit.org/show_bug.cgi?id=61824

Zasadniczo, gdy zastosujesz transformację 3D na osi z, indeks z nie może być już uwzględniony (jesteś teraz na trójwymiarowej płaszczyźnie renderowania, użyj różnych wartości z). Jeśli chcesz wrócić do renderowania 2D dla elementów podrzędnych, użyj transform-style: flat;.


13
Zasadniczo, gdy zastosujesz transformację 3D na osi z, indeks z nie może być już uwzględniony (jesteś teraz na trójwymiarowej płaszczyźnie renderowania, użyj różnych wartości z). Jeśli chcesz wrócić do renderowania 2D dla elementów podrzędnych, użyj transform-style: flat;.
— samy-delux

2
Więc w trybie "preserve-3d" musimy użyć osi z transformacji, aby ustawić kolejność, aw trybie płaskim powinniśmy użyć indeksu z. Błąd polega na tym, że indeks Z na safari jest uszkodzony w połączeniu z przyspieszonymi transformacjami sprzętowymi.
— Steven Lu

1
nie działa. Działa tylko wtedy, gdy usunę animowane style według klasy.
— fdrv

44

Jest to z całą pewnością związane z błędem zauważonym przez samy-delux. Powinno to dotyczyć tylko tych elementów, które są pozycjonowane jako bezwzględne lub względne. Aby rozwiązać ten problem, możesz zastosować następującą instrukcję css do każdego elementu, który jest umieszczony w ten sposób i powoduje problemy:

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

Spowoduje to zastosowanie przekształcenia do elementu bez faktycznego wykonywania transformacji, ale wpłynie na jego kolejność renderowania, tak aby znajdował się nad elementem powodującym problem.


Korzystając z przeglądarki Chrome (35.0.1916.114 m), stwierdziłem, że jeśli nie mam tej reguły, po odwróceniu elementu [transform: rotateY (180deg)], moduły obsługi kliknięć jQuery nie działają już dla tego elementu. Ponadto po przewróceniu pojawiają się problemy z artefaktami pozostającymi na ekranie, a zwłaszcza jeśli zmieniono ich krycie, chyba że istnieje translate3d! Ten artykuł pomógł sitepoint.com/fix-chrome-animation-flash-bug
— Philip Murphy

2
To właśnie rozwiązało bardzo przyklejony problem, który dotyczył dwóch stałych elementów, z których jeden zawierał element przekształcony w 3D. Przekształcony element 3D w zasadzie przepełniłby się i znalazłby się na innym elemencie, aż do zastosowania powyższej poprawki.
— Collin James,

1
nie działa. Działa tylko wtedy, gdy usunę animowane style według klasy.
— fdrv

12

Trochę późno, ale spróbuj umieścić elementy, które straciły indeks Z, umieszczając następujące, miałem problem podczas wykonywania ostatnio paralaksy i to bardzo pomogło.

transform-style: preserve-3d;

Oszczędza to nakładania

transform: translate3d(0,0,0);

Na innych elementach, które bardziej obciążają GPU


1
Gdy twoje elementy są trójwymiarowe, nie spodziewałbym się, że transformacja dodatkowo obciąży GPU. I tak trzeba wykonać obliczenia. Na czym to opierasz?
— Micros,

7

Czekam na przykład

Czy próbowałeś wykonać skalę transformacji (1)? Pamiętam, że miałem podobny problem i musiałem zmienić kolejność elementów w html i użyć transformacji, której nie potrzebowałem tylko dlatego, że zmienił się indeks Z użycia transformacji.

Jeśli się nie mylę, za każdym razem, gdy używasz transformacji, staje się ona najwyższym dostępnym indeksem z, a jest on uporządkowany według najbliższego elementu html znajdującego się na początku tagu. A więc od góry do dołu.

Mam nadzieję, że ta pomoc


6

z-index będzie działać z elementami div przekształconymi w 3D, jeśli nadasz styl elementowi stosowanemu w stosie -webkit-transform: translateZ(0px);

Fragment na codepen -> http://codepen.io/mrmoje/pen/yLIul

W przykładzie przyciski stack upi stack downpodnoszą i opuszczają indeks Z stopki (+/- 1) względem obracanego elementu (w tym przypadku obraz).


nie można ponownie kliknąć
— stosu

Hej @Moje, również zastanawiam się nad tym problemem. Nadal nie można ponownie kliknąć stosu.
— alchuang

Dlaczego nie pomyślałem o dodaniu ujemnego indeksu z do przetłumaczonego elementu? Dzięki
— Will

3

Nie udało mi się odtworzyć opisanego tutaj problemu. Niezależnie od tego, co robię, wartość indeksu z jest zachowywana podczas wszystkich przekształceń. Testuję przy użyciu Chromium (Google Chrome).

Trzeci argument funkcji translate3d manipuluje osią z elementu. Koncepcja jest podobna, ale nie dokładnie taka sama, jak w przypadku indeksu z ... Elementy o niższej osi z znajdują się pod elementami o wyższej wartości.

Wiem, że wypróbowałeś wartości trzeciego argumentu, aby pasowały do ​​zamierzonego indeksu z, ale problem polega na tym, że oś z nie wydaje się zmieniać podczas animacji CSS3. W poniższym przykładzie element najechany kursorem powinien znajdować się na górze, ale #element_a pozostaje na górze.

Jeśli dodam indeks z zarówno do zwykłego selektora, jak i do selektora: hover, wydaje się, że działa i pozwala na umieszczenie elementu na górze.

Chociaż nie jest to dokładnie to, czego szukałeś, to zachowanie zapewnia rozwiązanie. Wystarczy użyć translate3d i z-index, aby ustawić kolejność początkowego renderowania.

<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
To zadziałało dla mnie - dzięki! Dodałem do elementu, który chcę być „z przodu”: -webkit-transform: translate3d (0, 0, 1px);
— Sam Dutton

0

Innym sposobem obejścia tego jest to, że możesz utworzyć element nadrzędny i zastosować wszystkie inne przejścia z nim związane:

# 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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.