So verhindern Sie, dass sich das Rendern von Webkit-Text während des CSS-Übergangs ändert

81

Ich verwende CSS-Übergänge, um zwischen CSS-transformierten Zuständen zu wechseln (im Grunde genommen wird die Skalierung eines Elements geändert). Ich stelle fest, dass der Rest des Textes auf der Seite (in Webkit) beim Übergang des Elements dazu neigt, das Rendering geringfügig zu ändern, bis der Übergang abgeschlossen ist.

Geige: http://jsfiddle.net/russelluresti/UeNFK/

Ich habe auch festgestellt, dass dies bei meinen Headern nicht auftritt, auf denen sich das -webkit-font-smoothing: antialiasedEigenschafts- / Wertepaar befindet. Ich frage mich also, ob es eine Möglichkeit gibt, den Text in seinem Standard-Look (dem "Auto" -Wert für die Schriftglättung) beizubehalten und das Rendern während eines Übergangs nicht zu ändern.

Ich habe versucht, den Text explizit so einzustellen, dass er den Wert "auto" verwendet, aber das macht nichts. Ich sollte auch beachten, dass das Setzen der Schriftglättung auf "keine" auch das Blinken des Renderings während des Übergangs verhindert.

Jede Hilfe wird geschätzt.

Bearbeiten 1

Ich sollte beachten, dass ich unter OS X bin. Bei meinem Test in Chrome auf Parallels habe ich nicht festgestellt, dass sich die beiden unterschiedlichen Absätze unterschiedlich verhalten. Dies ist möglicherweise ein Problem, das nur Macs vorbehalten ist.

RussellUresti
quelle
21. Und die Safari-Version ist 6. Es passiert in beiden Browsern, was mich denken lässt, dass es sich um Webkit handelt und nicht um den Browser.
RussellUresti
Sowohl Antialias- als auch Alias-Absätze zeigen dasselbe Verhalten. Chrom Version 23.0.1270.0 Kanarienvogel | 21.0.1180.89 m | 5.17 Safari
Ich vermute, Sie sind in der Entwicklerversion von Chrome. Möglicherweise spielt das Betriebssystem dabei eine Rolle. Ich werde die Frage bearbeiten, um festzustellen, dass ich OSX verwende.
RussellUresti
1
Ich habe absolut keine Ahnung, warum dies funktioniert, aber ich füge '-webkit-transform: translateZ (0);' hinzu. zu '.antialiased {} scheinen es zu beheben. Es funktioniert sogar, wenn Sie es zu 'p {}' hinzufügen. Da ich nicht erklären kann, warum dies funktioniert, fühlte es sich nicht richtig an, es als Antwort zu geben. Hoffentlich hilft das!
Christofer Vilander
@Christofer Das macht sie konsistent - aber es lässt sie alle antialiasiert erscheinen (sie sind alle dünnerer Text). Ich versuche, den nicht antialiasierten Text (den ersten Absatz) in seinem Standardstil zu belassen (der etwas kühner erscheint als der antialiasierte Text).
RussellUresti

Antworten:

83

Ich glaube, ich habe eine Lösung gefunden:

-webkit-transform: translateZ(0px);

Das Erzwingen der Hardwarebeschleunigung für das übergeordnete Element scheint das Problem zu lösen ...

BEARBEITEN Wie kommentiert, deaktiviert dieser Hack die Schriftglättung und kann die Textwiedergabe abhängig von Ihren Schriftarten, Ihrem Browser und Ihrem Betriebssystem beeinträchtigen!

Armel Larcier
quelle
Versuchte die Schriftglättung und es hat nicht funktioniert. Versuchte dies, es funktionierte perfekt
locrizak
Dies hat mir nicht das gewünschte Ergebnis für dieses angegebene Problem gebracht, aber dies hat mir geholfen, andere CSS-Übergangsprobleme zu beheben, die ich hatte (wie seltsam blinkenden Text beim Ausblenden / Anzeigen von Inhalten innerhalb des Übergangselements).
RussellUresti
3
Funktioniert bei mir nicht, während -webkit-font-Smoothing: Antialiasing; und -webkit-backface-sichtbarkeit: versteckt; funktioniert. Credits gehen hier stackoverflow.com/questions/11589985/…
F Lekschas
+1 fantastisch, dies ist die einzige Methode, die für die Situation funktioniert hat, in der ich mich befand
Larry
4
Dies deaktiviert in erster Linie die Schriftglättung. Sie haben also zu Beginn des Übergangs keine Schriftglättung, während des Übergangs keine Schriftglättung und am Ende keine Schriftglättung. Also keine Änderung der Schriftglättung, aber auch überhaupt keine Schriftglättung.
Yunzen
45

UPDATE August 2020

Sie müssen Safari nicht mehr mit einer Medienabfrage ansprechen, um die Glättung von Subpixel-Schriftarten zu aktivieren. Der Standardwert ist in Ordnung.

Jedoch , obwohl es Subpixel - Schriftglättung standardmäßig verwendet, gibt es eine signifikante Fliege in der Salbe in Chrome Schriftglättung, für alle , die eine Suche konsistenten Darstellung von Text .

  1. Dies ist Chrome's Rendering von hellem Text auf dunklem Hintergrund hell auf dunkel
  2. Dies ist Chrome's Rendering von dunklem Text auf hellem Hintergrund dunkel auf hell

Schauen Sie sich die Größe des Ganzen im obigen Buchstaben e an. Der helle Text auf dunklem Hintergrund wird mit einer spürbar höheren Gewichtung gerendert als der dunkle Text auf hellem Hintergrund (mit identischem CSS-Schriftstil).

Eine Lösung für Websites, die die Dunkel / Hell-Themeneinstellung des Benutzers berücksichtigen, besteht darin, Chrome mit einer Medienabfrage anzusprechen, die auf den Dunkelmodus beschränkt ist, und diese wie folgt auf Nicht-Subpixel-Glättung umzustellen:

@media screen
and (-webkit-min-device-pixel-ratio: 0)
and (min-resolution: 0.001dpcm)
and (prefers-color-scheme: dark) {
  body {
    -webkit-font-smoothing: antialiased;
  }
}

Das Ergebnis :

dunkel auf hellhell auf dunkel antialiased

Eine weitaus gleichmäßigere Textgewichtung, unabhängig davon, ob Licht auf Dunkel oder Dunkel auf Licht gerendert wird.

Schauen Sie sich den direkten Vergleich von vorher und nachher an: hell auf dunkelhell auf dunkel antialiased

- -

UPDATE Mai 2018

-webkit-font-smoothing: subpixel-antialiasedhat jetzt keine Wirkung in Chrome, aber in Safari verbessert es die Dinge noch sehr, ABER NUR AUF RETINA. Ohne es in Safari auf Retina-Bildschirmen ist Text dünn und fade, während Text damit das richtige Gewicht hat. Wenn Sie dies jedoch auf Nicht-Retina-Displays in Safari verwenden (insbesondere bei geringen Gewichtswerten), ist Text eine Katastrophe. Es wird dringend empfohlen, eine Medienabfrage zu verwenden:

@media screen and (-webkit-min-device-pixel-ratio: 2) {
  body {
    -webkit-font-smoothing: subpixel-antialiased;
  }
}

Die explizite Einstellung -webkit-font-smoothing: subpixel-antialiasedist die derzeit beste Lösung, wenn Sie den dünneren Antialias-Text zumindest teilweise vermeiden möchten.

--tl; dr--

Sowohl in Safari als auch in Chrome, wo das Standard-Rendering von Schriftarten Subpixel-Antialiasing verwendet, führt jedes CSS, das GPU-basiertes Rendering erzwingt, wie die obigen Vorschläge, eine Transformation mit translateZ oder sogar nur einen Skalierungsübergang zu verwenden, dazu, dass Safari und Chrome automatisch "aufgeben" "Bei der Glättung von Subpixel-Antialiasing-Schriftarten wechseln Sie stattdessen zu nur Antialiasing-Text, der vor allem auf Safari viel heller und dünner aussieht.

Andere Antworten konzentrierten sich auf die Aufrechterhaltung eines konstanten Renderings, indem einfach die Schriftglättung auf den dünneren Antiailias-Text eingestellt oder erzwungen wurde. Meines Erachtens verschlechtert die Verwendung von translateZ oder der verborgenen Rückseite die Qualität der Textwiedergabe erheblich. Die beste Lösung, wenn der Text nur konsistent bleiben soll und Sie mit dem dünneren Text einverstanden sind, ist nur die Verwendung -webkit-font-smoothing: antialiased. Die explizite Einstellung hat -webkit-font-smoothing: subpixel-antialiasedjedoch tatsächlich einige Auswirkungen - der Text ändert sich immer noch geringfügig und ist bei Übergängen, die auf der GPU gerendert werden, sichtbar dünner, aber nicht so dünn wie ohne diese Einstellung. Es sieht also so aus, als würde dies zumindest teilweise die Umstellung auf geraden Antiailias-Text verhindern.

atomlos
quelle
2
Vielen Dank für eine tolle Zusammenfassung!
Denis Gorbatschow
2
Dies ist die beste Lösung. Alle anderen verschlechtern die
Textwiedergabe
Lebensretter für mich! Vielen Dank. Vermeidet das plötzliche Umschalten auf Subpixel-Rendering nach einem CSS-Übergang. Zumindest beim Opazitätsübergang bleibt die Schriftart auch während des Übergangs beim Rendern von Subpixeln (theoretisch immer standardmäßig). Toll!
Garavani
beste Lösung für uns! Vielen Dank
Kernel
Danke, ich war vor über einem Jahr darauf gestoßen und habe alles vergessen. Dies ist die einzige Lösung, die das beschriebene Problem für mich gelöst hat.
Iain Collins
19

Ich habe festgestellt, dass fast jedes Mal, wenn ich Grafikprobleme (Flackern / Stottern / Abgehacktheit / usw.) aufgrund eines Übergangs mit -webkit-backface-sichtbarkeit habe: versteckt; auf die Elemente, die wirken, neigt dazu, das Problem zu lösen.

Jordan Borth
quelle
3
Dies ist die (derzeit) richtige Antwort. Meines Wissens wurde Webkit-Font-Smoothing vor einiger Zeit entfernt, sollte wieder hinzugefügt werden, funktioniert aber derzeit bei mir in der neuesten Version von Chrome nicht. Der translateZ-Trick scheint auch nicht mehr zu funktionieren. Ich denke, das kann sich jederzeit wieder ändern. : /
Jemand
3
Dies führte dazu, dass ein Text für mich unscharf wurde.
John
8

Um Änderungen der Textwiedergabe aufgrund von Hardwarebeschleunigung zu verhindern, können Sie entweder:

  1. Stellen Sie den gesamten Text auf -webkit-font-Smoothing: Antialiasing ein. Dies bedeutet, dass der Text dünner und nicht mit Subpixeln versehen ist.

  2. Wenn Sie möchten, dass Text, der von der Hardwarebeschleunigung betroffen ist, ein Subpixel-Antialiasing aufweist (die Standardart der Schriftglättung), wird dieser Subpixel-Antialiasing (zumindest) beibehalten, wenn Sie diesen Text in eine Eingabe ohne Rahmen und deaktiviert einfügen unter Chrome unter Mac OS X). Ich habe dies nicht auf anderen Plattformen getestet, aber wenn Subpixel-Antialiasing wichtig ist, können Sie diesen Trick zumindest anwenden.

Joran Greef
quelle
Ich habe die Option 2 (Trick mit Eingabeelement) unter Win8.1 und Chrome 47 getestet und sie funktioniert nicht.
Paya
3

Das hat bei mir funktioniert. Ich hoffe es hilft. Gefunden in anderen Stackoverflow-Post.

-webkit-font-smoothing:antialiased;
-webkit-backface-visibility:hidden;
Daniel Almeida
quelle
1

Um die Rendering-Änderung zu verhindern, müssen Sie festlegen font-smoothing: antialiased(odernone ) .

Der Browser, der das Rendern von Subpixel-Schriftarten deaktiviert, ist wahrscheinlich ein Nebeneffekt der Hardwarebeschleunigung. Wenn sich der Hintergrund, vor dem Sie rendern, ständig ändert, kann der Text nicht auf einer separaten Ebene gerendert werden, da jeder Frame mit allen Hintergrundebenen verglichen werden muss. Dies könnte die Leistung erheblich beeinträchtigen.

Apple oft deaktivieren Subpixel Font-Glättung auf ihre eigenen Websites.

Henrik
quelle
Das Problem beim Festlegen der Schriftglättung auf Antialiasing besteht darin, dass der Text nicht so aussieht, wie ich es möchte. Ich möchte den visuellen Effekt, wenn Sie die Schriftglättung auf "Auto" (das kühnere Aussehen) setzen - aber wenn Sie dies tun, verschiebt sich der Text während eines Übergangs. Mein Ziel ist es also, immer den kühnen Look von "auto" beizubehalten.
RussellUresti
1
Sie können dies umgehen, indem Sie keine Hardwarebeschleunigung verwenden. Verwenden Sie einen Timer in jQuery und führen Sie den Übergang von Hand durch (ohne CSS-Übergang). Ich bin mir nicht sicher, ob ich es empfehlen würde, da Leistung und Laufruhe schlechter werden.
Henrik
Es stimmt, ich könnte einfach jQuery verwenden, um es zu animieren ... Das ist möglicherweise die einzige Lösung, wenn es keine andere Lösung gibt.
RussellUresti
1

Zusätzlich zu den oben genannten Lösungen ( -webkit-transform: translateZ(0px)auf dem Element und -webkit-font-smoothing: antialiasedauf der Seite) können sich einige Elemente immer noch schlecht verhalten. Für mich war es Platzhaltertext in einem Eingabeelement: Verwenden Sie dazuposition:relative

WraithKenny
quelle
-1

Ich hatte das gleiche Problem. Lesen Sie es sorgfältig:

Ich stelle fest, dass der Rest des Textes auf der Seite (in Webkit) beim Übergang des Elements dazu neigt, das Rendering geringfügig zu ändern, bis der Übergang abgeschlossen ist.

Keine der oben genannten Lösungen schien zu funktionieren. Allerdings Einstellung (Dinge wie)

#myanimation { -webkit-transform: translateZ(0px); }

auf dem Element, das die Animation hat hat, hat funktioniert.

Indem Sie das animierte Element in die GPU-Ebene bringen, nehmen Sie es aus dem normalen Fluss des Seiten-Renderings heraus (Dinge wie z-Index funktionieren beispielsweise auch nicht mehr). Als Nebeneffekt beeinflussen sich die Animation und der Rest der Seite nicht mehr gegenseitig.

Wenn es sich auf das Rendern Ihrer Schrift auswirkt, gilt dies natürlich nur für das animierte Element. Ich sehe keinen Unterschied in meinem Chrome.

Commonpike
quelle
Ich stehe korrigiert. Ich sehe Änderungen in der Schriftwiedergabe im Rest der Seite, auch an Stellen, an denen translateZ (0) nicht angewendet wird.
Commonpike
Dies ist das einzige, was für mich funktioniert hat, als ich Schriftarten-Symbole hatte, die verschwommen wurden. Wendete die Transformation auf die Abschnitte an, die animiert wurden, und löste das Problem.
Bill
Alter, das wurde schon vor 2 Jahren beantwortet. Rechts oben ... Genau dieselbe Antwort / Code.
NiCk Newman
Ja, mein einziger Punkt war, dass Sie -webkit-transformdas Element mit der Animation platzieren müssen , um zu verhindern, dass Änderungen an anderen Elementen auf der Seite gerendert werden . aber wie kommentiert, funktionierte es eine Weile und hörte auf zu funktionieren, als ich später Teile der Seite änderte.
Commonpike