it-roy-ru.com

Фиксированные позиции не работают при использовании -webkit-transform

Я использую -webkit-transform (и -moz-transform/-o-transform), чтобы вращать div. Также добавлено фиксированное положение, чтобы div прокручивал пользователя вниз.

В Firefox он работает нормально, но в браузерах на основе webkit он не работает. После использования -webkit-transform фиксированная позиция больше не работает! Как это возможно?

138
iSenne

После некоторых исследований на веб-сайте Chromium был опубликован отчет bug об этой проблеме, поэтому браузеры Webkit не могут одновременно визуализировать эти два эффекта. 

Я бы предложил добавить немного CSS для Webkit в вашу таблицу стилей и сделать преобразованный div изображением и использовать его в качестве фона.

@media screen and (-webkit-min-device-pixel-ratio:0) {
  /* Webkit-specific CSS here (Chrome and Safari) */

  #transformed_div {
    /* styles here, background image etc */
  }
}

Так что сейчас вам придется делать это по старинке, пока браузеры Webkit не догонят FF.

Правка: По состоянию на 24.10.2012 ошибка не была решена.


Похоже, что это не ошибка, а аспект спецификации из-за двух эффектов, требующих отдельных систем координат и порядков наложения. Как объясняется в этом ответе .

77
Kyle

Спецификация CSS Transforms объясняет это поведение. Элементы с преобразованиями действуют как содержащий блок для потомков с фиксированным положением, поэтому position: fixed под чем-то с преобразованием больше не имеет фиксированного поведения.

Они работают, когда применяются к одному и тому же элементу; элемент будет позиционирован как фиксированный, а затем преобразован.

78
smfr

Для тех, кто обнаруживает, что их фоновые изображения исчезают в Chrome из-за той же проблемы с background-attachment: исправлено; - это было мое решение:

// run js if Chrome is being used
if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
    // set background-attachment back to the default of 'scroll'
    $('.imagebg').css('background-attachment', 'scroll');

    // move the background-position according to the div's y position
    $(window).scroll(function(){

        scrollTop = $(window).scrollTop();
        photoTop = $('.imagebg').offset().top;
        distance = (photoTop - scrollTop);
        $('.imagebg').css('background-position', 'center ' + (distance*-1) + 'px');

    });
}  
7
Jayden Lawson

Август 2016 и фиксированная позиция и анимация/трансформация все еще остаются проблемой. Единственное решение, которое сработало для меня, - это создать анимацию для дочернего элемента, которая занимает больше времени.

6
defligra

На самом деле я нашел другой способ исправить эту «ошибку»:

У меня есть элемент контейнера, который содержит страницу с анимацией CSS3. Когда страница завершила анимацию, свойство css3 имеет значение: transform: translate (0,0) ;. Итак, я просто удалил эту строку, и все заработало как надо - position: fixed отображается правильно. Когда для перевода страницы применяется класс css, добавляется свойство translate и анимация css3 также работает.

Пример:

.page {
     top: 50px;
     position: absolute;
     transition: ease 0.6s all;
     /* -webkit-transform: translate(0, 0); */
     /* transform: translate(0,0); */
 }
 .page.hide {
     -webkit-transform: translate(100%, 0);
     transform: translate(-100%, 0);    
 }

Демо: http://jsfiddle.net/ZWcD9/

3
lowselfesteemsucks

Что-то (немного странное), которое сработало для меня, это вместо этого position:sticky:

.fixed {
     position: sticky;
}
3
yckart

Добавление -webkit-transform к фиксированному элементу решило проблему для меня.

.fixed_element {
   -webkit-transform: translateZ(0);
   position: fixed;
   ....
} 
2
Ron

Возможно, из-за ошибки в Chrome, поскольку я не могу воспроизвести ни в Safari, ни в Firefox, но это работает в Chrome 40.0.2214.111 http://jsbin.com/hacame/1/edit?html,css,output

Это очень специфическая структура, поэтому она ни в коем случае не является универсально применимым однострочным исправлением CSS, но, возможно, кто-то может воспользоваться им, чтобы заставить его работать в Safari и Firefox.

1
Kerry Johnson

в моем проекте phonegap преобразование webkit -webkit-transform: translateZ (0); работал как шарм .. Он уже работал в Chrome и Safari, а не в мобильном браузере .. Также может быть еще одна проблема - WRAPPER DIVs не завершены в некоторых случаях. мы применяем чистый класс в случае плавающих DIV.

<div class="Clear"></div> .Clear, .Clearfix{clear:both;}
1
abksharma

Вот что работает для меня на всех протестированных браузерах и мобильных устройствах (Chrome, IE, Firefox, Safari, iPad, iphone 5 и 6, Android).

img.ui-li-thumb {
    position: absolute;
    left: 1px;
    top: 50%;

    -ms-transform: translateY(-50%);
    -webkit-transform: translateY(-50%);
    -moz-transform: translateY(-50%);
    -o-transform: translateY(-50%);
    transform: translateY(-50%);
}
0
TrackABill.com

Если вы можете использовать javascript в качестве опции, это может быть обходной путь для позиционирования фиксированного элемента позиции относительно окна, когда он находится внутри преобразованного элемента:

  let fixedEl // some node that you is position 
              // fixed inside of an element that has a transform

  const rect = fixedEl.getBoundingClientRect()
  const distanceFromWindowTop = rect.top
  const distanceFromWindwoLeft = rect.left
  let top = fixedEl.offsetTop
  let left = fixedEl.offsetLeft

  if(distanceFromWindowTop !== relativeTop) {
    top = -distanceFromWindowTop
    fixedEl.style.top = `${top}px`
  }

  if(distanceFromWindowLeft !== relativeLeft) {
    left = -distanceFromWindowLeft
    fixedEl.style.left = `${left}px`
  }

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

0
Adrian Adkison

Добавьте динамический класс, пока элемент преобразуется .$('#elementId').addClass('transformed'). Затем объявите в css,

.translatX(@x) { 
     -webkit-transform: translateX(@X); 
             transform: translateX(@x);
      //All other subsidaries as -moz-transform, -o-transform and -ms-transform 
}

затем

#elementId { 
      -webkit-transform: none; 
              transform: none;
}

затем

.transformed {
    #elementId { 
        .translateX(@neededValue);
    }
}

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

0
mr.G

фиксированное положение элемента нарушается, если вы применяете преобразование к любому предку.

<div style='position:fixed;-.*-transform:scale(2)'>...</div> //ok

<div style='-.*-transform:scale(2)'>
      <div style='position:fixed'>...</div> // broken
</div>
0
bortunac

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

#element_with_transform {
  -webkit-transform: none;
  transform: none;
}
0
makkasi