Alles begann mit einem Tweet
Kontext
Damit wir alle auf dem gleichen Stand sind: Was Hugo meint, ist, dass es zwei verschiedene Möglichkeiten gibt, Elemente zu „bewegen“.
- Geben Sie dem Element eine `relative`, `absolute` oder `fixed` Positionierung. Dann können Sie `top`, `right`, `left`, `bottom` (oder eine beliebige Kombination davon) verwenden, um die Objekte zu verschieben.
- Stellen Sie sicher, dass das Element einen `display`-Wert von `block` oder `inline-block` hat und verwenden Sie dann den Transformationswert `translate()`, `translateX()` oder `translateY()`, um das Element zu bewegen.
„Besser“, v1
Mein erster Gedanke, was „besser“ in diesem Zusammenhang bedeutet, ist, welche Methode unter verschiedenen Umständen besser geeignet ist. Was mich zu der Aussage bringt: **„verwechseln Sie Positionierung nicht mit Design-Bewegung.“**
Ein Beispiel. Sie haben einen Button. Sie möchten einen Effekt auf diesen Button anwenden, sodass er in seinem `:active`-Zustand um 2 Pixel nach unten ruckelt, um einen „gedrückten“ Effekt zu simulieren. Das ist eine Design-Bewegung, die mit `translate()` erfolgen sollte. Sie könnten es mit `top` oder `bottom` und relativer Positionierung tun, aber dann vermischen Sie die Konzepte von Positionierung und Design-Bewegung.
Nehmen wir an, Sie positionieren einen Button irgendwo anders in der App absolut (völlig legitim). Wenn dann `:active` auf den Button angewendet wird, wird dieser Button wahrscheinlich irgendwohin fliegen, wo Sie ihn nicht erwartet haben, und ihn möglicherweise unklickbar machen.
Die Verwendung von `translate()` „ruckelt“ das Element immer von seiner aktuellen Position aus, was perfekt für einen solchen Effekt oder jede design-spezifische Bewegung ist.
„Besser“, v2
Was Hugo wahrscheinlich meinte, war die **Performance**. Es ist zu einer gängigen allgemeinen Empfehlung geworden, dass die Verwendung von `translate()` zum Bewegen von Elementen eine bessere Performance hat als `top/right/bottom/left`. Aber hält die Daten stand? Schauen wir uns das an.
Zuerst habe ich eine sehr einfache Animation eines roten Balls erstellt, der hin und her animiert.
Für mein bloßes Auge, im neuesten stabilen Chrome (23) und auf einem Retina MacBook Pro mit viel RAM, ist die `translate()`-Version tatsächlich etwas performanter. Ich kann bei der `top/left`-Version sehr leichte Ruckler erkennen. Wahrnehmung ist wichtig, aber schauen wir uns die echten Daten an.
In den Chrome-Entwicklertools können Sie zum Tab „Timeline“ wechseln, dann zu „Frames“ und dann auf den Kreis „Aufnehmen“-Button unten drücken. Wenn die Animation läuft, starten Sie die Aufnahme für eine Weile und stoppen Sie sie dann. Die Daten sind am besten, wenn keine anderen Webseiten sichtbar sind, insbesondere wenn diese Animationen durchführen.
Bei der `top/left`-Version sehen Sie gelegentliche Spitzen über der Linie „60 FPS“ oder sechzig Bildern pro Sekunde. Das ist die Linie, unter der wir versuchen zu bleiben, da sie einer perfekt flüssigen wahrgenommenen Bewegung entspricht.


Aber warten Sie
Das wird komplizierter. Ich begann, mit Paul Irish zu sprechen, der am Google Chrome-Team arbeitet. Paul dachte, dass dies „Paints“ so einfach sind, dass es wahrscheinlich kein bester echter Leistungsindikator ist. Paul nahm meine Demos und erhöhte die Komplexität. Anstelle eines roten Balls, Josh Hibberts MacBook Pro. Anstelle eines weißen Hintergrunds, Nate Eagles Polsterung.
Die Dinge wurden seltsam, als **Pauls Beispiele das Gegenteil von dem zeigten, was wir erwartet hatten.** Die `top/left`-Version sieht flüssiger aus als die `translate()`-Version. Und überraschenderweise zeigten die Frames-Timeline keine großen Unterschiede.
Hier begann Paul, tiefer in diese seltsame Welt einzutauchen. Er fand viele interessante Dinge heraus! Paul sprach mit einem anderen Paul im Chrome-Team, Paul Lewis, der zustimmte, dass es „intelligenter ist, `translate()` für Design-Bewegungen zu verwenden.“ Aber er fügte hinzu, dass es mehr gibt als nur die Bildrate. Mit `translate()` erhalten Sie Sub-Pixel-Animationen, eine Art Verwischen zwischen Pixeln, das normalerweise zu flüssigeren Animationen führt.
Mit Subpixel-[Animationen] verlieren Sie Klarheit, was richtig ist. Der Schlüssel ist, länger bei gerundeten Werten an den Extremen zu verweilen, damit Ihre Augen die Befriedigung der Klarheit, aber die Flüssigkeit der Bewegung erhalten.
Paul Irish gräbt viel tiefer
Ich gebe das einfach an Paul weiter. Er hat ein 13-minütiges Video erstellt, das Sie ansehen sollten. Es erklärt all diese ausgefallenen GPU-Sachen und Subpixel-Rendering und all das.
Sehr interessant. Toller Tweet, Hugo!
Danke, Chris und Paul, dass Sie sich die Zeit genommen haben, das zu klären.
Hallo Chris, vielen Dank für diesen Beitrag! Sie und Paul haben großartige Arbeit geleistet, um das Thema hier zu behandeln. Problem gelöst! ;)
Toller Tweet, Hugo!
Es war eine gute Erfahrung, besonders Pauls Screencast zu sehen.
Hallo, ich habe es mit Chrome ausprobiert und es war mit Translate viel flüssiger. Seltsam!
Übergänge und Animationen sind auf Webkit fast immer flüssiger :)
Ja, Translate war für mich flüssiger. o.O
Bei Firefox dasselbe für mich.
Toller Artikel Chris.
Die ersten beiden roten Ball-Links führen zum selben Ort! :)
Korrekter Link für den oberen/linken: http://codepen.io/chriscoyier/pen/pBCax
Entschuldigung, ich sollte den vollständigen Link anstelle des Pen-Links verwenden: http://codepen.io/chriscoyier/full/pBCax
(Schade, dass ich meinen ersten Kommentar nicht bearbeiten kann. Dort gehen unglaublich viele vertikale Pixel verloren.)
Danke, behoben. Ich werde es verbergen, da es ein temporäres Problem war.
Ich habe auf die Antwort auf diese Frage gewartet. Vielen Dank, dass Sie beide die Zeit für diese gründliche Recherche aufgewendet haben!
In Safari 6 war die Translate-Version viel flüssiger als die Top/Left-Version.
Ich stimme zu.
Auf iOS6 ist Translate ebenfalls viel schneller.
Ja, es ist wichtig zu sehen, wie alle anderen Browser mit den verschiedenen Methoden performen, sowohl Desktop als auch Mobil. Die gute Nachricht ist: Sie performen alle besser mit Translate.
Dasselbe für Firefox Nightly 20.
In Chrome auf dem iPad ist die Translate-Version viel flüssiger als die Top/Left-Version.
Die Top/Left-Version sieht hässlich aus!
Das Ändern von top/left/right/left verschiebt das DOM-Element im Fenster. Das bedeutet, dass alles neu berechnet und neu gezeichnet werden muss (da diese Änderungen beeinflussen können, wie sich andere Elemente verhalten).
Bei der Verwendung von translate() berühren Sie nichts im DOM und wie es sich verhält. Nur wie es gerendert wird. Das ist ein RIESIGER Unterschied, der den Leistungsunterschied erklärt und auch die Dinge anders funktionieren lässt. Das Element selbst bewegt sich mit all seinem CSS, anstatt seine CSS-Parameter zu ändern.
Sie können diesen Unterschied sehen, indem Sie `background-attachment: fixed` verwenden und dann `top/left`-Werte ändern oder `translateX()`-Werte ändern.
Und folglich bewegt sich, korrigieren Sie mich, wenn ich falsch liege, die klickbare Fläche eines Elements bei der trbl-Methode mit, aber NICHT bei Translate?
Andy, da sich die gesamte Ebene bewegt, glaube ich, dass sich die „klickbare Fläche“ mitbewegt: http://jsfiddle.net/joshnh/pyagP/
Da haben Sie Recht. Ich schwor, ich hätte irgendwo eine Demo gesehen, bei der sich das Ding bei :hover bewegte und der Hotspot an Ort und Stelle blieb... Muss etwas anderes gewesen sein.
Und ein mutiger Mensch, der hier JSFiddle anstelle von CodePen benutzt! :)
Wie CM bemerkte, ist der erste Demo-Link stärker.
Ich muss auch anderen Kommentatoren zustimmen, für die schwere Demo ist in Chrome Translate flüssiger, was das Gegenteil von dem ist, was Ihr Beitrag vorschlägt.
stark = falsch* :P
So eine interessante Lektüre, wie üblich! Danke!
Das fühlt sich wie eine dumme Frage an, aber gibt es Unterschiede in der Browserkompatibilität der beiden Methoden? Und/oder gibt es Unterschiede in der einfachen Erstellung von browserkompatiblem CSS? (Ist eine davon kompatibler, begünstigt eine davon einfacheres Coding mit weniger CSS-Workarounds usw.?)
Die Dinge wurden seltsam, als Pauls Beispiele das Gegenteil von dem zeigten, was wir erwartet hatten. Die Top/Left-Version sieht flüssiger aus als die Translate()-Version. – In Firefox 17.0.1 unter Win7 x64 sieht `translate()` WEITAUS flüssiger aus als `top/left`, aber nur, nachdem das Objekt sich das erste Mal bewegt hat. Beim ersten Bewegen des Objekts sieht es tatsächlich ruckelig aus.
Subtil, aber sehr interessant, die Variation in Ihren Beispielen zu sehen, jetzt weiß ich, dass es sich lohnt, beide Wege auszuprobieren, wenn die Dinge nicht ganz richtig aussehen.
Das ist großartig! Ich war immer ein `top/left/bottom/right`-Typ, wenn es um Dinge wie gleitende Menüs ging, einfach weil Translate in IE8 nicht unterstützt wird und ich keine zusätzliche CSS schreiben wollte. Dies beweist jedoch eindeutig, dass die Verwendung von Translate die zusätzliche Anstrengung wert ist. Zur Kenntnis genommen.
Mit IE10 sieht Translate() perfekt flüssig aus, aber das andere ist mit 10 MBPs ziemlich ruckelig. Der Ball sieht bei beiden gleich aus. Selbst mit einem MBP ist Top/Left etwas ruckelig.
Meine Antwort war also doch richtig. Gut!
Mir ist aufgefallen, dass die SwipeJS-Bibliothek `translate` für 1:1 Swipes und Animationen auf Smartphones verwendet hat. Ich war neugierig, warum der Autor Translate benutzte, also habe ich es durch einen negativen Margin und dann durch `position:relative` ersetzt, um es zu vergleichen. Der Unterschied war riesig, also habe ich schnell zu `translate` zurückgewechselt. Auf Mobilgeräten, wo die Rechenleistung begrenzt ist, ist das der Unterschied zwischen sehr ruckeligen und flüssigen Animationen.
Ich habe gelesen, dass man Translate verwenden musste, um die Hardwarebeschleunigung von iPhones zu aktivieren…
Ich habe festgestellt, dass dies der Fall war, als ich ein einfaches Dropdown mit jQuery slideDown/slideUp erstellt habe… es war auf dem iPhone ruckelig… aber als ich nur Klassen wechselte und Übergänge und Translate verwendete, war die Leistung viel besser…
Ich wäre daran interessiert zu sehen, wie translate3d abschneidet. Ich benutze translate3d in meinem Liquid Slider, weil ich dachte, es gäbe einen Leistungsschub, insbesondere auf iOS-Geräten. Ist das noch korrekt?
Vielen Dank, dass Sie das beide gepostet haben. Es war großartig, die Chrome-Entwicklertools für einige meiner eigenen Animationen auszuprobieren. Weiter so!
Hier unter FF17 ist translate() VIEL besser, besonders wenn ich „Add 10 more Macbooks“ klicke.
Bei der Verwendung von top/left ist die Animation sehr ruckelig und die Unterelemente (wie der Deckel des geöffneten Laptops) bewegen sich nicht alle zusammen mit dem Rest des Macbooks.
Mein Gehirn explodiert.
Ich habe auch Pauls Video angesehen, fantastisch. Ich habe vor einiger Zeit ein Projekt gemacht, das sehr stark auf Links/Rechts-Animationen setzte, ich muss es vielleicht zurückgehen und aktualisieren.
Sehr guter Artikel. Danke fürs Teilen!
Schöner Tweet und Beitrag!
Die Diskussion ist gut und sie könnte auf andere Browser erweitert werden, wie Firefox oder Opera für gute C
Interessanterweise, auf Ubuntu mit Firefox, war von der roten Ball-Version die Top/Left-Version etwas flüssiger. Bei dem Macbook-Beispiel war Translate deutlich flüssiger.
Das beweist nur, warum wöchentliche Besuche bei css-tricks/Coyierland unerlässlich sind. Sie gehen jeder kleinen Nuance des Webs mit wissenschaftlicher Disziplin nach und bohren sich immer wieder zu genauen Informationen durch. Eine der besten Informationsressourcen des www. Klein, aber interessante Frage, brillante Links und Antworten für fortgeschrittenes Wissen. Wieder mal Kudos.
Hat jemand meinen Namen gesagt?
Ich bin entzückt, dass meine superkomplexen radialen Verläufe endlich der Menschheit von Nutzen waren.
Ich weiß, ich bin etwas spät zur Party, aber ich dachte, ihr findet das vielleicht interessant…
Ich sehe, dass `top/left` in den meisten Browsern **VIEL** schneller ist, wenn mehr Elemente animiert werden. Sehen Sie den Vergleich unter http://www.greensock.com/js/speed.html. Die `translate()`-Technik ist unter starker Belastung buchstäblich 400 % langsamer (oder mehr). Die einzige Ausnahme ist iOS Safari. Seltsam.
Daher denke ich, dass die Leistungssteigerungen, die Sie mit `translate()` erzielen, nur in bestimmten Szenarien anwendbar sind, z. B. wenn einige Elemente gleichzeitig animiert werden und/oder Effekte wie `opacity`, `box-shadow` usw. verwendet werden. Aber es gibt eine Schwelle, an der der „Hardwarebeschleunigungs“-Saft tatsächlich zu einem erheblichen Engpass wird (dank Paul Lewis für diesen Hinweis). Dann wieder kann das Subpixel-Rendering nett sein, wenn Sie nicht viele Elemente animieren.
Tolle Diskussion, Leute.
Nur um meine Ergebnisse hinzuzufügen: Chrome aktuell (23.0.1271.97) sieht im komplexen Beispiel mit `translate()` mit 1 Macbook viel flüssiger aus, aber am seltsamsten ist, dass sich die Leistung **nicht** verschlechtert, wenn tonne weitere Macbook-Bilder hinzugefügt werden, während `top/left` exponentiell langsamer wird! Es muss irgendeine Art von Super-Duper-Optimierung geben, die ich niemals verstehen könnte.
Guter Beitrag, ich habe festgestellt, dass die neuesten Builds von FF und Chrome viel flüssiger sind, aber Tatsache bleibt, dass wir uns in Richtung vieler schöner CSS3-Effekte bewegen wollen, aber die Nutzer halten uns bei Projekten zurück… Am Ende des Tages muss ein Entwickler eine Website erstellen, die für die Benutzerbasis so nutzbar wie möglich ist.
Muy Interesante me gusto :D
Vorsicht, wenn Sie diese Methode verwenden, um ein Panel mit Formularelementen zu animieren (Firefox-Bug): Wenn diese Elemente den Fokus haben (oder Texte eingegeben werden), bewegt sich das Panel unabhängig von allen Werten, die Sie zur Erkennung oder Neupositionierung des Panels verwenden (und die Werte werden nicht synchron sein). Es ist nervig. Es gibt irgendwo einen Bug-Report bei Mozilla.
Bei den Macbook-Beispielen ist Translate in Firefox und Chrome sehr flüssig und Top/Left ist ruckelig für mich. Wie sagen Sie, dass Top/Left flüssiger ist??