Feste Positionen funktionieren bei Verwendung von -webkit-transform nicht


155

Ich benutze -webkit-transform (und -moz-transform / -o-transform), um ein div zu drehen. Außerdem wurde eine feste Position hinzugefügt, damit das Div mit dem Benutzer nach unten scrollt.

In Firefox funktioniert es gut, aber in Webkit-basierten Browsern ist es kaputt. Nach der Verwendung der -webkit-Transformation funktioniert die festgelegte Position nicht mehr! Wie ist das möglich?


4
Eine Demoseite hilft häufig bei der Beantwortung von Fragen. Mit jsbin.com können Sie temporäre Seiten erstellen, um das Problem zu veranschaulichen, wenn Sie keinen Link zu Ihrer Website erstellen möchten.
Rich Bradshaw

jsfiddle.net ist ein weiteres gutes Beispiel für einen temporären Bearbeitungsbehälter.
Kyle

@ Rich Bradshaw jsbin.com ist sehr nett. Wusste es bis jetzt nicht. Die meisten meiner Projekte werden lokal ausgeführt, daher werde ich sie beim nächsten Mal verwenden. Tnx
iSenne

7
Es funktioniert nicht in Firefox überhaupt.
vsync

3
Immer noch ein Problem im Jahr 2017. Scheint, dass sie immer noch an der "Es ist eine Funktion, kein Fehler!" Argument ...
Max

Antworten:


87

Nach einigen Recherchen wurde auf der Chromium- Website ein Fehlerbericht zu diesem Problem veröffentlicht. Bisher können Webkit-Browser diese beiden Effekte nicht gleichzeitig rendern.

Ich würde vorschlagen, dass Sie Ihrem Stylesheet nur Webkit-CSS hinzufügen und das transformierte Div zu einem Bild machen und es als Hintergrund verwenden.

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

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

Im Moment müssen Sie dies also auf die altmodische Weise tun, bis die Webkit-Browser FF einholen.

BEARBEITEN: Bis zum 24.10.2012 wurde der Fehler nicht behoben.


Dies scheint kein Fehler zu sein, sondern ein Aspekt der Spezifikation aufgrund der beiden Effekte, die separate Koordinatensysteme und Stapelreihenfolgen erfordern. Wie in dieser Antwort erklärt .


34
Noch mehr Jahre später noch nicht gelöst. Ziemlich traurig.
Amalgovinus

9
Nach dieser Antwort ist es kein Fehler, sondern Teil der Spezifikation.
Michael

15
Lehnen Sie sich zurück und schauen Sie zu - ich wette, es wird sein 10-jähriges Jubiläum feiern
lzl124631x

29
30. August 2017, Kapitänsprotokoll. Wir sind auch auf die seltsame Anomalie gestoßen, die vor so langer Zeit von anderen Kapitänen beschrieben wurde. Eine Lösung muss noch implementiert werden.
Luoruize

14
Dies ist der Fehler, vor dem mich der Vater meines Vaters gewarnt hat.
danjones_mcr

96

Die CSS-Transformationsspezifikation erklärt dieses Verhalten. Elemente mit Transformationen fungieren als enthaltender Block für Nachkommen mit fester Position. Position: Fixiert unter etwas mit einer Transformation hat kein festes Verhalten mehr.

Sie funktionieren, wenn sie auf dasselbe Element angewendet werden. Das Element wird als fest positioniert und dann transformiert.


9
Das ist die einzig hilfreiche und richtige Antwort. Beenden Sie die Übersetzung des übergeordneten Elements und übersetzen Sie die untergeordneten Elemente, zu denen das feste Element gehört. Hier ist meine Geige: JSFIDDLE
Falk

2
und was ist, wenn ich auch ein festes Element transformieren möchte?
Marc

7

Für alle, die ihre Hintergrundbilder finden, verschwinden sie in Chrome aufgrund des gleichen Problems mit dem Hintergrundanhang: behoben; - das war meine Lösung:

// 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

Etwas (ein bisschen hacky), das für mich funktioniert hat, ist position:stickystattdessen:

.fixed {
     position: sticky;
}

5
updates.html5rocks.com/2012/08/… ah yeah .. aber noch nicht gut unterstützt, wie es scheint
coiso

1
klebrig ist anders. Das Hauptproblem ist, dass wir mit Fixed die Position des Containers ignorieren wollen (sehr nützlich, z. B. für Deckkraftanimationen). Ich kann nicht glauben, dass dieser Fehler noch Jahre später vorhanden ist. Schrecklich.
FlorianB

6

August 2016 und feste Position & Animation / Transformation ist immer noch ein Problem. Die einzige Lösung, die für mich funktioniert hat, war die Erstellung einer Animation für das untergeordnete Element, die länger dauert.


Bitte beantworten Sie neue Fragen. Diese Fragen brauchen Sie mehr als die Person, die 2010 Fragen gestellt hat. Sie müssen das Problem inzwischen gelöst haben, finden Sie nicht? Auch diese Frage hat bereits eine akzeptierte Antwort.
Umair Farooq

5
Nee! Es ist immer noch ein Problem ... die Person, die die Frage gestellt hat, hat möglicherweise eine andere Lösung gefunden - aber ich habe diesen Thread aus einem bestimmten Grund gefunden.
Defligra

Wie du möchtest. Ich habe diesen Kommentar hinterlassen, als ich die ersten Fragen von Leuten durchgesehen habe. Und da Sie erst heute beigetreten sind und es Ihre erste Antwort und auch eine späte Antwort war, habe ich diesen Kommentar hinterlassen. Ich habe nicht abgelehnt. Das ist eine gute Chance für dich.
Umair Farooq

1
@UmairFarooq Vielleicht wäre es nutzlos, eine andere Frage zu stellen, da sie als Duplikat markiert werden könnte. Ich bin nur mit einer Google-Suche hierher gekommen und fand diese Frage nützlich, auch Defligra- Antwort.
KoMah

3

Eigentlich habe ich einen anderen Weg gefunden, um diesen "Fehler" zu beheben:

Ich habe Container-Element, das Seite mit CSS3-Animationen enthält. Wenn die Seite die Animation abgeschlossen hat, hat die Eigenschaft css3 den Wert: transform: translate (0,0);. Also habe ich gerade diese Zeile entfernt und alles hat so funktioniert, wie es sollte - Position: fest wird richtig angezeigt. Wenn die CSS-Klasse zum Übersetzen der Seite angewendet wird, wird die Eigenschaft translate hinzugefügt und die CSS3-Animation funktioniert ebenfalls.

Beispiel:

.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);    
 }

Demo: http://jsfiddle.net/ZWcD9/


1
Für mich war es die Tatsache, dass diese Stile auf dem Wrapper mit dem festen Element vorhanden waren, die verhinderte, dass das feste Element klebrig wurde: -webkit-perspektive: 1000; -webkit-transform-style: konserviere-3d; Hat diese abgenommen und alles funktioniert gut. Es waren sowieso fragwürdige Optimierungen!
Amalgovinus

Das Entfernen der Transformation ist wahrscheinlich die bisher beste Problemumgehung. So etwas wie ein Einblenden sollte nach Abschluss entfernbar sein, ohne das Erscheinungsbild des Elements zu beeinträchtigen. Eigentlich bin ich mir nicht sicher, was ein herumhängender transformX (0) für das Rendern der Leistung bedeuten würde, wenn überhaupt; Es könnte entweder ignoriert werden oder die Leistung beeinträchtigen oder es verbessern, indem eine Art 3D-Beschleunigung erzwungen wird. Wer weiß. In jedem Fall können die CSS-Klassen für die Transformation einfach entfernt werden, sobald eine Animation abgeschlossen ist oder kurz bevor ein festes Element hinzugefügt wird.
Triynko

1

in meinem Phonegap-Projekt die Webkit-Transformation -webkit-transform: translateZ (0); Lief wie am Schnürchen. Es funktionierte bereits in Chrome und Safari, nur nicht im mobilen Browser. Es kann auch ein weiteres Problem geben: WRAPPER DIVs sind in einigen Fällen nicht abgeschlossen. Bei schwebenden DIVs wenden wir eine klare Klasse an.

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

1

Wahrscheinlich aufgrund eines Fehlers in Chrome, da ich weder in Safari noch in Firefox replizieren kann, aber dies funktioniert in Chrome 40.0.2214.111 http://jsbin.com/hacame/1/edit?html,css,output

Da es sich um eine ganz bestimmte Struktur handelt, handelt es sich keineswegs um ein universell einsetzbares einzeiliges CSS-Update, aber vielleicht kann jemand daran basteln, damit es in Safari und Firefox funktioniert.


1

Ich hatte dieses Problem beim Versuch, React-Color mit React-Swipeable-Views (rsw) zu implementieren. Das Problem für mich war, dass rsw translate(-100%, 0)auf ein Registerkartenfeld angewendet wird , das die über den Vollbildmodus hinzugefügte Standard- Feststellungsdivision aufhebt, die beim Klicken das Farbauswahlmodell schließt.

Für mich bestand die Lösung darin, die entgegengesetzte Transformation auf das feste Element anzuwenden (in diesem Fall, translate(100%, 0)wodurch mein Problem behoben wurde. Ich bin mir nicht sicher, ob dies in anderen Fällen nützlich ist, dachte aber, ich würde es trotzdem teilen.

Hier ist ein Beispiel, das zeigt, was ich oben beschrieben habe:

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


0

Das Hinzufügen des -webkit-transformzum festen Element hat das Problem für mich gelöst.

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

20
Das hat bei mir nicht funktioniert. Können Sie eine funktionierende Demo erstellen?
Alex

4
Dies hat ein Problem für mich in Chrome, FWIW, behoben. Danke Ron.
Chris

3
Vielen Dank, dies hat mir ein Problem behoben. Rettete mein Leben!
Styke

1
@ Neil Monroe, Android 2.3 ist eine ganz neue Geschichte. Es unterstützt die feste Positionierung überhaupt nicht :)
Wiseman

8
Hier ist eine Geige, bei der die Verwendung translateZ(0) NICHT funktioniert. Es ist wahr, dass es manchmal funktioniert, ich habe Gelegenheiten gesehen, in denen es funktioniert hat. Aber ich kann es immer noch nicht eingrenzen.
Zequez

0

Folgendes funktioniert für mich auf allen getesteten Browsern und Mobilgeräten (Chrome, IE, Firefox, Safari, iPad, iPhone 5 und 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
Warum die Abstimmungen? Es wäre schön, wenn Sie einen Kommentar dazu abgeben würden, warum Sie meine Antwort abgelehnt haben.
Murf

0

Die feste Position eines Elements wird unterbrochen, wenn Sie die Transformation auf einen Vorfahren anwenden.

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

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

0

Wenn Sie Javascript als Option verwenden können, kann dies eine Problemumgehung sein, um ein positionsfestes Element relativ zum Fenster zu positionieren, wenn es sich in einem transformierten Element befindet:

  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`
  }

Zugegeben, Sie müssen auch Ihre Höhe und Breite anpassen, da fixedEldie Berechnung anhand des Containers erfolgt. Das hängt von Ihrem Anwendungsfall ab, aber dies ermöglicht es Ihnen, die festgelegte Position vorhersehbar festzulegen, unabhängig vom Container.


0

Fügen Sie eine dynamische Klasse hinzu, während sich das Element transformiert. $('#elementId').addClass('transformed'). Dann deklarieren Sie in CSS,

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

dann

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

dann

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

Jetzt Position: Fest, wenn ein Top- und ein Z-Index-Eigenschaftswert für ein untergeordnetes Element bereitgestellt werden. Funktioniert einwandfrei und bleibt fest, bis sich das übergeordnete Element transformiert. Wenn die Umwandlung zurückgesetzt wird, wird das untergeordnete Element wieder als fest angezeigt. Dies sollte die Situation verschlechtern, wenn Sie tatsächlich eine Navigationsseitenleiste verwenden, die beim Klicken um- und geschlossen werden kann, und Sie haben eine Registerkarte, die beim Scrollen auf der Seite klebrig bleiben sollte.


0

In meinem Fall habe ich herausgefunden, dass wir transform: translateX () nicht vor transform: translateY () verwenden können. Wenn wir beide verwenden möchten, sollten wir transform: translate (,) verwenden.


-1

Bitte stimmen Sie nicht ab, da dies keine genaue Antwort ist, sondern jemandem helfen könnte, da dies ein schneller Weg ist, um die Transformation auszuschalten. Wenn Sie die Transformation für das übergeordnete Element wirklich nicht benötigen und möchten, dass Ihre feste Position wieder funktioniert:

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

1
Dies ist wirklich im Titel der Frage
Eugene Pankov

@EugenePankov Im Titel wird 'none' nicht angezeigt. Es war das, was mein Problem behoben hat, und im Allgemeinen schlägt niemand vor, es auszuschalten. Dies ist zwar keine genaue Antwort auf diese Frage, aber es könnte jemandem helfen, der keine Transformation verwenden möchte und die Transformation aus einer anderen Bibliothek stammt. Ich möchte also keine Stimmen nach oben, aber bitte nicht nach unten stimmen. Ich werde meine Frage so bearbeiten, dass ich keine Up-Abstimmung möchte.
Makkasi
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.