Виправлені позиції не працюють при використанні -webkit-перетворення


155

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

У Firefox він працює чудово, але у веб-браузерах, які працюють на веб-сайтах, він порушений. Після використання -webkit-трансформації фіксована позиція більше не працює! Як це можливо?


4
Демонстраційна сторінка часто допомагає людям відповідати на запитання - jsbin.com дозволяє створювати тимчасові сторінки, щоб проілюструвати проблему, якщо ви не хочете посилатися на свій сайт.
Річ Бредшоу

jsfiddle.net - ще один хороший приклад тимчасового кошика для редагування.
Кайл

@Rich Bradshaw jsbin.com дуже приємно. Не знав цього досі. Більшість моїх проектів я виконую на локальному рівні, тому я буду використовувати його наступного разу. Tnx
iSenne

7
Це зовсім не добре працює у Firefox.
vsync

3
Проблема все ще залишається в 2017 році. Здається, вони все ще дотримуються "Це особливість, а не помилка!" аргумент ...
Макс

Відповіді:


87

Після деяких досліджень на веб-сайті Chromium з’явився звіт про помилки щодо цієї проблеми, тому браузери Webkit не можуть одночасно рендер цих двох ефектів.

Я б запропонував додати кілька таблиць стилів 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.

EDIT: Станом на 24.10.2012 помилка не була усунена.


Здається, це не помилка, а аспект специфікації, зумовлений двома ефектами, що вимагають окремих систем координат та порядків укладання. Як пояснено у цій відповіді .


34
Ще більше років по тому ще не вирішено. Досить сумно.
Амальговінус

9
Відповідно до цієї відповіді, це не помилка, а частина специфікації.
MichaelRushton

15
сидіти і дивитись - я вважаю, що він доживе до свого 10-річного ювілею
lzl124631x

29
30 серпня 2017 року, журнал капітана. Ми також стикалися з дивною аномалією, яку так давно описали інші капітани. Рішення ще належить реалізувати.
Luoruize

14
Це помилка, про яку попередив мене батько мого батька.
danjones_mcr

96

Специфікація CSS Transforms пояснює цю поведінку. Елементи з перетвореннями виконують роль блоку, що містить нащадків з фіксованою позицією, тому положення: закріплене під чим-небудь з перетворенням більше не має фіксованої поведінки.

Вони виконують роботу при застосуванні до одного елемента; елемент буде розташований як закріплений, а потім перетворений.


9
Це єдина корисна і правильна відповідь. Перестаньте перекладати батьківський елемент і перекладіть дочірні елементи, де нерухомий елемент є його частиною. Ось моя загадка
Falk

2
а що робити, якщо я теж хочу перетворити нерухомий елемент?
Марк

7

Для всіх, хто знайде їх фонові зображення, зникають у Chrome через одну і ту ж проблему з фоновим вкладеним файлом: виправлено; - це було моє рішення:

// 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');

    });
}  

6

Щось (трохи гакітне), що працювало для мене, це position:sticky:

.fixed {
     position: sticky;
}

5
updates.html5rocks.com/2012/08/… ах так .. але не дуже підтримується, але здається
coiso

1
липкий різний. Основна проблема полягає в тому, що за допомогою виправлених ми хочемо ігнорувати позицію контейнера (дуже корисно. Для анімації непрозорості, наприклад). Я не можу повірити, що ця помилка все ще існує через роки. Жахливий.
FlorianB

6

Серпень 2016 року та виправлена ​​позиція та анімація / трансформація залишаються проблемою. Єдине рішення, яке працювало для мене - було створити анімацію для дочірнього елемента, яка займає більше часу.


Будь ласка, дайте відповідь на нові запитання. Ці питання потрібні тобі більше, ніж людині, яка задала питання у 2010 році. Вони, мабуть, вирішили проблему до цього часу, ти не думаєш? Також на це питання вже є прийнята відповідь.
Umair Farooq

5
Ні! Це все ще проблема ... людина, яка поставила запитання, може знайти інше рішення - але я знайшов цю тему чомусь.
дефлігра

Як хочеш. Я залишив цей коментар, переглядаючи перші питання людей. А оскільки ви приєдналися саме сьогодні, це була ваша перша відповідь, а також пізня відповідь, тому я залишив цей коментар. Я не став голосом. Це хороший шанс для вас.
Umair Farooq

1
@UmairFarooq, можливо, задавати інше питання було б марно, оскільки його можна було б позначити як дублікат. Я прийшов сюди просто з пошуком Google, і я знайшов це питання корисним, дефлігра відповідь теж.
koMah

3

Насправді я знайшов інший спосіб виправити цю "помилку":

У мене є елемент контейнера, який містить сторінку з анімацією css3. Коли сторінка завершила анімацію, властивість css3 має значення: transform: translate (0,0) ;. Отже, я просто видалив цей рядок, і все працювало як слід - позиція: фіксована відображається належним чином. Коли для перекладу сторінки застосовується клас 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/


1
Для мене був факт наявності цих стилів на обгортці, що містить нерухомий елемент, що заважав фіксованому бути липким: -webkit-перспектива: 1000; -webkit-перетворення-стиль: зберегти-3d; Узяв їх, і все працює добре. Вони все-таки були сумнівними оптимізаціями!
Амальговінус

Видалення трансформації будь-якими способами - це, мабуть, найкраще рішення досі. Щось подібне до вимкнення, після завершення має бути знімним, не впливаючи на зовнішній вигляд елемента. Насправді, я не впевнений, що, якщо перетворитися на трансформаціюX (0), може зробити рендеринг, якщо взагалі щось є; його можна або проігнорувати, або пошкодити продуктивність, або покращити його, примушуючи якесь 3D-прискорення. Хто знає. У будь-якому випадку, коли анімація завершена, або навіть перед тим, як до неї буде доданий фіксований елемент, можна просто видалити CSS-класи для перетворення.
Трайнко

1

у моєму проекті fonegap перетворення webkit -webkit-transform: translateZ (0); працював як шарм. Він уже працював у chrome та safari, тільки не мобільний браузер. також може виникнути ще одне питання - WRAPPER DIV не завершені в деяких випадках. ми застосовуємо чіткий клас у випадку плаваючих DIV.

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

1

Можливо, через помилку в Chrome, оскільки я не можу копіювати в Safari чи Firefox, але це працює в Chrome 40.0.2214.111 http://jsbin.com/hacame/1/edit?html,css,output

Це дуже особлива структура, тому це аж ніяк не універсально застосований односкладений файл css fix, але, можливо, хтось може поцікавитися, щоб він працював у Safari та Firefox.


1

У мене виникла ця проблема, намагаючись реалізувати колір реагування за допомогою перегляду реакцій (rsw). Проблема для мене полягала в тому, що rsw застосовується translate(-100%, 0)до панелі вкладок, яка розбиває встановлену за замовчуванням діву позицію, додану на весь екран, яка при натисканні закриває модель вибору кольору.

Для мене рішенням було застосувати протилежне перетворення до фіксованого елемента (у цьому випадку translate(100%, 0)це вирішило мою проблему. Я не впевнений, чи це корисно в інших випадках, але я думав, що все одно поділяться.

Ось приклад, що показує те, що я описав вище:

https://codepen.io/relativemc/pen/VwweEez


0

Додавання -webkit-transformдо закріпленого елемента вирішило проблему для мене.

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

20
Це не працювало для мене. Чи можете ви створити демонстраційну версію роботи?
alex

4
Це вирішило проблему для мене в Chrome, FWIW. Дякую Рон.
Кріс

3
Дякую, це вирішило мені проблему. Врятувало мені життя!
стик

1
@Neil Monroe, Android 2.3 - це зовсім нова історія. Це взагалі не підтримує фіксованого позиціонування :)
Wiseman

8
Ось Скрипка, де використання translateZ(0) НЕ працює. Це правда, що це працює іноді, я бачив випадки, коли це працювало. Але я все одно не можу звузити це.
Зекес

0

Ось що для мене працює у всіх перевірених браузерах та мобільних пристроях (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%);
}

2
Чому голоси? Було б добре, якби ви дали коментар щодо того, чому ви проголосували за мою відповідь?
Мерф

0

фіксоване положення елемента порушується, якщо застосувати перетворення до будь-якого предка.

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

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

0

Якщо ви можете використовувати 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

Додайте динамічний клас, поки елемент перетворюється. $('#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);
    }
}

Тепер позиція: виправлена, коли на дочірньому елементі надаються значення властивостей верхнього та z-індексу, просто працюють добре і залишаються фіксованими, поки батьківський елемент не трансформується. Після повернення перетворення дочірній елемент з'являється як фіксований знову. Це може полегшити ситуацію, якщо ви фактично використовуєте бічну панель навігації, яка перемикається та закривається при натисканні, і у вас є набір вкладок, який повинен залишатися липким під час прокрутки сторінки.


0

в моєму випадку я виявив, що ми не можемо використовувати transform: translateX () перед трансформацією: translateY (). Якщо ми хочемо використовувати обидва, ми повинні використовувати transform: translate (,).


-1

Будь ласка, не голосуйте, бо це не точна відповідь, але може допомогти комусь, оскільки це швидкий спосіб просто відключити трансформацію. Якщо вам справді не потрібна трансформація на батьківському рівні, і ви хочете, щоб ваше фіксоване положення знову працювало:

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

1
Це, мовляв, насправді в назві питання
Євген Паньков

@EugenePankov У назві не бачимо "жодного". Саме це вирішило мою проблему, і взагалі ніхто не пропонує її вимкнути. Хоча це не точна відповідь на це питання, але це може допомогти тому, хто не хоче використовувати перетворення, і перетворення відбувається з іншої бібліотеки. Тому я не хочу голосувати, але, будь ласка, не відмовляйтесь від голосу. Я відредагую своє запитання, щоб сказати, що я не хочу голосувати вгору.
makkasi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.