z-index css потерян после преобразования webkit translate3d


98

У меня есть два абсолютно позиционированных элемента div, которые перекрываются. Оба установили значения z-index через css. Я использую translate3dпреобразование webkit для анимации этих элементов за пределами экрана, а затем обратно на экран. После преобразования элементы больше не соблюдают свои установленные z-indexзначения.

Может ли кто-нибудь объяснить, что происходит с z-index / stack-order элементов div, когда я выполняю преобразование webkit для них? И объясните, что я могу сделать, чтобы сохранить порядок стека элементов div?

Вот еще немного информации о том, как я выполняю преобразование.

Перед преобразованием каждый элемент получает эти два значения перехода webkit, установленные через css (я использую jQuery для выполнения .css()вызовов функций:

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

Затем элемент анимируется с помощью translate3d -webkit-transform:

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

Кстати, я попытался установить для третьего параметра translate3dнесколько разных значений, чтобы попытаться воспроизвести порядок стека в трехмерном пространстве, но безуспешно.

Кроме того, браузеры iPhone / iPad и Android - это мой целевой браузер, в котором должен работать этот код. Оба поддерживают переходы через webkit.


Вы можете разместить ссылку, чтобы увидеть пример?
Littlemad

1
Я встретил ту же проблему. У меня есть один тег <iframe> со стилем внутреннего элемента «-webkit-transform: translate3d (0,0,0)», чтобы заставить 3D-ускорение. Оказывается, внешний фрейм с более высоким z-index всегда скрывается внутренним элементом iframe. Просто визуально скрытый, я могу "щелкнуть" невидимый внешний элемент. Это происходит только в Mobile Safari.
Морган Ченг,

Я потратил 10 часов, выясняя, что из-за этого мой код не работает. Уф
Dikeneko

Ответы:


52

Это может быть связано с: https://bugs.webkit.org/show_bug.cgi?id=61824

В основном, когда вы применяете 3D-преобразование к оси z, z-index больше не может быть учтен (теперь вы находитесь в трехмерной плоскости рендеринга, используйте другие z-значения). Если вы хотите вернуться к 2D-рендерингу дочерних элементов, используйте transform-style: flat;.


13
В основном, когда вы применяете 3D-преобразование к оси z, z-index больше не может быть учтен (теперь вы находитесь в трехмерной плоскости рендеринга, используйте другие z-значения). Если вы хотите вернуться к 2D-рендерингу дочерних элементов, используйте transform-style: flat;.
samy-delux

2
Таким образом, в режиме «preserve-3d» мы должны использовать ось z преобразования, чтобы установить порядок, а в плоском режиме мы должны использовать z-index. Ошибка заключается в том, что z-index в Safari не работает в сочетании с HW-ускоренными преобразованиями.
Стивен Лу

1
не работает. Работает, только если я удалю анимированные стили по классам.
fdrv

44

Это определенно связано с ошибкой, отмеченной samy-delux. Это должно затронуть только те элементы, которые позиционируются как абсолютные или относительные. Чтобы решить эту проблему, вы можете применить следующий оператор css к каждому элементу, который расположен таким образом и вызывает проблемы:

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

Это применит преобразование к элементу, фактически не выполняя преобразование, но влияя на его порядок рендеринга, чтобы он находился над элементом, вызывающим проблему.


Используя Chrome (35.0.1916.114 m), я обнаружил, что если бы у меня не было этого правила, после того, как элемент был перевернут [transform: rotateY (180deg)], обработчики кликов jQuery больше не работали для этого элемента. Кроме того, после переворота возникают проблемы с артефактами, остающимися на экране, особенно если их непрозрачность была изменена, если не присутствует translate3d! Эта статья помогла sitepoint.com/fix-chrome-animation-flash-bug
Филип Мерфи

2
Это просто решило для меня очень неприятную проблему, связанную с двумя фиксированными элементами, один из которых содержит трехмерный преобразованный элемент. Преобразованный трехмерный элемент будет в основном переполняться и располагаться поверх другого элемента, пока не будет применено исправление, указанное выше.
Коллин Джеймс

1
не работает. Работает, только если я удалю анимированные стили по классам.
fdrv

12

Немного поздно, но попробуйте надеть элементы, которые потеряли свой Z-индекс, разместив следующее: у меня недавно возникла проблема, когда я делал некоторые вещи с параллаксом, и это очень помогло.

transform-style: preserve-3d;

Это экономит

transform: translate3d(0,0,0);

На других элементах, которые увеличивают нагрузку на графический процессор


1
Когда ваши элементы трехмерны, я бы не ожидал, что преобразование приведет к дополнительной нагрузке на графический процессор. Расчеты все равно нужно производить. На чем вы это основываете?
Micros

7

Жду примера

Вы пробовали сделать масштаб трансформации (1)? Я помню, что у меня была аналогичная проблема, и мне пришлось переупорядочить html-порядок элементов и использовать преобразование, которое мне не нужно, только потому, что изменился z-индекс использования преобразования.

Если я не ошибаюсь, каждый раз, когда вы используете преобразование, он становится наивысшим доступным z-индексом и упорядочивается по ближайшему элементу html к началу тега. Итак, снизу вверх.

Я надеюсь что это поможет


6

z-index будет работать с трехмерными преобразованными div, если вы стилизуете штабелируемый элемент с помощью -webkit-transform: translateZ(0px);

Фрагмент кода на codepen -> http://codepen.io/mrmoje/pen/yLIul

В этом примере кнопки stack upи stack downподнимают и опускают z-index нижнего колонтитула (+/- 1) относительно повернутого элемента (в данном случае img).


стек нельзя щелкнуть снова
clevertension

Привет, @Moje, меня тоже интересует эта проблема. Стек вверх по-прежнему нельзя щелкнуть снова.
alchuang

Почему я не подумал добавить к переведенному элементу отрицательный z-index? Спасибо
Will

3

Мне не удалось воспроизвести описанную здесь проблему. Независимо от того, что я делаю, значение z-index сохраняется во всех преобразованиях. Тестирую с помощью Chromium (Google Chrome).

Третий аргумент функции translate3d управляет осью z элемента. Концепция похожа, но не совсем такая же, как z-index ... Элементы с более низкой осью z находятся под элементами с более высоким значением.

Я знаю, что вы пробовали значения третьего аргумента, чтобы они соответствовали предполагаемому z-индексу, но проблема в том, что ось z не меняется во время анимации CSS3. В следующем примере зависший элемент должен быть сверху, а #element_a остается сверху.

Если я добавлю z-index как к обычному селектору, так и к селектору: hover, он, похоже, сработает и позволит элементу, на который наведен курсор, быть самым верхним.

Хотя это не совсем то, что вы искали, такое поведение дает решение. Вам просто нужно использовать translate3d и z-index, чтобы установить порядок начального рендеринга.

<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
У меня это сработало - спасибо! Я добавил следующее к элементу, который хочу быть «впереди»: -webkit-transform: translate3d (0, 0, 1px);
Сэм Даттон,

0

Другой способ обойти это - создать родительский элемент и применить все другие переходы, связанные с ним:

# 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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.