CSS移行中にWebkitテキストレンダリングの変更を防ぐ方法


81

CSSトランジションを使用して、CSS変換された状態間を遷移します(基本的には要素のスケールを遷移します)。要素が遷移しているとき、ページ上の残りのテキスト(Webkit内)は、遷移が完了するまでレンダリングをわずかに変更する傾向があることに気付きました。

フィドル: http //jsfiddle.net/russelluresti/UeNFK/

私はまた、これが私のヘッダーでは発生しないことに気づきました。 -webkit-font-smoothing: antialiasedプロパティと値のペアました。したがって、テキストをデフォルトの外観(フォントスムージングの「自動」値)に維持し、遷移中にレンダリングを変更しない方法はありますか?

「auto」値を使用するようにテキストを明示的に設定しようとしましたが、何もしません。font-smoothingを「none」に設定すると、トランジション中にレンダリングが点滅するのを防ぐことにも注意してください。

どんな助けでも大歓迎です。

編集1

私はOSXを使用していることに注意してください。ParallelsのChromeでのテストを見ると、2つの異なる段落の動作が異なることがわかりませんでした。したがって、これはMacに固有の問題である可能性があります。


21.Safariのバージョンは6です。両方のブラウザで発生するため、ブラウザではなくWebkitだと思います。
RussellUresti 2012

アンチエイリアス処理された段落とエイリアス処理された段落の両方が同じ動作を示しています。クロームバージョン23.0.1270.0カナリア| 21.0.1180.89 m | 5.17サファリ

Chromeの開発リリースを使用していると思います。ただし、OSがこれに関与している可能性があります。質問を編集して、OSXを使用していることに注意します。
RussellUresti 2012

1
なぜこれが機能するのかまったくわかりませんが、「-webkit-transform:translateZ(0);」を追加します。'.antialiased {}に修正されたようです。'p {}'に追加しても機能します。なぜこれが機能するのか説明できないので、答えとして提供するのは正しくないと感じました。お役に立てば幸いです。
Christofer Vilander 2012

@Christoferこれにより、一貫性が保たれますが、すべてアンチエイリアス処理されたように見えます(すべて薄いテキストです)。アンチエイリアスされていないテキスト(最初の段落)をデフォルトのスタイル(アンチエイリアスされたテキストよりも少し太字で表示されている)のままにしようとしています。
RussellUresti 2012

回答:


83

私は解決策を見つけたと思います:

-webkit-transform: translateZ(0px);

親要素にハードウェアアクセラレーション強制すると、問題が解決するようです...

編集 コメントされているように、このハックはフォントスムージングを無効にし、フォント、ブラウザ、OSによってはテキストのレンダリングを低下させる可能性があります!


フォントスムージングを試しましたが、機能しませんでした。これを試してみましたが、完全に機能しました
locrizak 2013

これは、この述べられた問題に対して望ましい結果を私に与えませんでしたが、これは私が持っていた他のCSS遷移の問題を修正するのに役立ちました(遷移要素内のコンテンツを非表示/表示するときの奇妙な点滅テキストなど)。
RussellUresti 2013

3
-webkit-font-smoothing:antialiased;に対して、私には機能しません。および-webkit-backface-visibility:hidden; 動作します。クレジットはここに行くstackoverflow.com/questions/11589985/...
F Lekschas

+1すごい、これは私が自分自身を見つけた状況で機能した唯一の方法です
Larry

4
これにより、そもそもフォントスムージングが無効になります。したがって、トランジションの開始時にフォントスムージングがなく、トランジション中にフォントスムージングがなく、終了時にフォントスムージングがありません。したがって、フォントスムージングの変更はありませんが、フォントスムージングもまったくありません。
yunzen 2013

45

2020年8月の更新

サブピクセルフォントのスムージングを有効にするために、メディアクエリでSafariをターゲットにする必要がなくなりました。デフォルトで問題ありません。

ただし、デフォルトではサブピクセルフォントスムージングを使用しますが、テキストの一貫したレンダリングを探している人にとっては、Chromeのフォントスムージング軟膏に大きな飛躍あります

  1. これは、暗い背景に明るいテキストをChromeでレンダリングしたものです。 ライトオンダーク
  2. これは、明るい背景に暗いテキストをChromeでレンダリングしたものです。 ダークオンライト

上記の文字eで全体のサイズを見てください。暗い背景の明るいテキストは、明るい背景の暗いテキストよりもかなり重い重みでレンダリングされます(同じcssフォントスタイルで)。

ユーザーのダーク/ライトテーマ設定を尊重するサイトの1つの解決策は、ダークモードに制限されたメディアクエリでChromeをターゲットにし、次のように非サブピクセルスムージングに切り替えることです。

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

結果 :

ダークオンライトダークアンチエイリアスライト

ライトオンダークまたはダークオンライトのどちらをレンダリングするかに関係なく、はるかに一貫したテキストの重み。

前後の比較を並べて確認してください。 ライトオンダークダークアンチエイリアスライト

-

2018年5月の更新

-webkit-font-smoothing: subpixel-antialiasedChromeでは効果がありませんが、Safariではそれでも大幅に改善されますが、RETINAでのみです。Safariの網膜画面にそれがないとテキストは薄くて無味乾燥ですが、それがあるとテキストは適切な重みを持ちます。しかし、SafariのRetinaディスプレイ以外でこれを使用する場合(特に軽量の値で)、テキストは大惨事になります。メディアクエリの使用を強くお勧めします:

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

-webkit-font-smoothing: subpixel-antialiased薄いアンチエイリアステキストを少なくとも部分的に回避したい場合は、明示的に設定することが現在の最善の解決策です。

--tl; dr--

デフォルトのフォントレンダリングがサブピクセルアンチエイリアスを使用するSafariとChromeの両方で、上記の提案のように、translateZを使用した変換、または単にスケール遷移を使用するようにGPUベースのレンダリングを強制するCSSを使用すると、SafariとChromeは自動的に「あきらめます」 「サブピクセルアンチエイリアスフォントスムージングでは、代わりにアンチエイリアステキストのみに切り替えます。これは、特にSafariで、はるかに明るく薄く見えます。

他の応答は、フォントスムージングをより薄いアンチエイリアステキストに設定または強制することによって、一定のレンダリングを維持することに焦点を合わせています。私の目には、translateZまたはbackface hiddenを使用すると、テキストレンダリングの品質が大幅に低下します-webkit-font-smoothing: antialiased。テキストの一貫性を維持し、薄いテキストで問題がない場合は、を使用するのが最善の解決策です。ただし、明示的に設定すると、-webkit-font-smoothing: subpixel-antialiased実際にはある程度の効果があります。テキストはわずかに変化し、GPUでレンダリングされたトランジション中には目に見えて薄くなりますが、この設定がない場合ほど薄くはなりません。したがって、これは少なくとも部分的に、まっすぐなアンチエイリアステキストへの切り替えを妨げるように見えます。


2
素晴らしい記事をありがとう!
デニスゴルバチョフ

2
これが最善の解決策です。他のすべてはテキストレンダリングを劣化させます。これはOPが特に回避
fregante 2014

私にとって命の恩人!ありがとう。css遷移後に突然サブピクセルレンダリングに切り替わるのを回避します。少なくとも不透明度の遷移では、これにより、遷移中もフォントが(理論的には常にデフォルトで)サブピクセルレンダリングされたままになります。すごい!
ガラヴァニ2014年

私たちにとって最良の解決策!ありがとう
カーネル

おかげで、私は1年以上前にこれに出くわし、それについてすべて忘れていました。これは私のために説明された問題を解決した唯一の解決策です。
イアン・コリンズ

20

-webkit-backface-visibility:hidden;を使用して、トランジションが原因でグラフィックの問題(ちらつき/途切れ/途切れなど)が発生するたびに気づきました。作用している要素で問題を解決する傾向があります。


3
これは(現在)正解です。私の知る限り、webkit-font-smoothingは少し前に削除され、再び追加されるはずでしたが、現在、最新バージョンのChromeでは機能しません。translateZトリックも機能しなくなったようです。これはいつでもまた変わる可能性があると思います。:/
Mantriur 2013

3
これにより、一部のテキストがぼやけてしまいました。
ジョン

8

ハードウェアアクセラレーションによるテキストレンダリングの変更を防ぐには、次のいずれかを実行できます。

  1. すべてのテキストを-webkit-font-smoothing:antialiasedに設定します。これは、テキストが薄く、サブピクセルのアンチエイリアス処理されていないことを意味します。

  2. ハードウェアアクセラレーションの影響を受けるテキストをサブピクセルアンチエイリアス(デフォルトの種類のフォントスムージング)にしたい場合は、そのテキストを入力内に境界線なしで無効にすると、そのサブピクセルはアンチエイリアスされたままになります(少なくともMac OS XのChromeの場合)。私はこれを他のプラットフォームでテストしていませんが、サブピクセルのアンチエイリアスが重要な場合は、少なくともこのトリックを使用できます。


Win8.1とChrome47でオプション2(入力要素を使用したトリック)をテストしましたが、機能しません。
パヤ


3

これは私のために働いたものです。それが役に立てば幸い。他のstackoverflowの投稿で見つかりました。

-webkit-font-smoothing:antialiased;
-webkit-backface-visibility:hidden;

1

レンダリングの変更を防ぐには、設定する必要がありますfont-smoothing: antialiased(またはnone)。

ブラウザがサブピクセルフォントのレンダリングを無効にすると、ハードウェアアクセラレーションの副作用になる可能性があります。レンダリングする背景が絶えず変化している場合、各フレームをすべての背景レイヤーに対してチェックする必要があるため、テキストを個別のレイヤーにレンダリングすることはできません。これにより、パフォーマンスが大幅に低下する可能性があります。

Appleは 自社サイトでサブピクセルフォントスムージングを無効にすることがよくあります。


フォントスムージングをアンチエイリアスに設定する際の問題は、テキストが希望どおりに表示されないことです。フォントスムージングを「自動」(より太字の外観)に設定する視覚効果が必要ですが、これを行うと、遷移中にテキストがシフトします。ですから、私の目標は、常に「自動」の大胆な外観を維持することです。
RussellUresti 2012

1
ハードウェアアクセラレーションを使用しないことで回避できます。jQueryでタイマーを使用し、手動で遷移を実行します(CSS遷移なし)。パフォーマンスと滑らかさが悪くなるので、私はそれをお勧めするかどうかはわかりません。
ヘンリック

確かに、jQueryを使用してアニメーション化することもできます...他に解決策がない場合は、それが唯一の解決策かもしれません。
RussellUresti 2012

1

上記の解決策(-webkit-transform: translateZ(0px)要素および-webkit-font-smoothing: antialiasedページ上)に加えて、一部の要素は依然として正常に動作しない可能性があります。私にとっては、入力要素のプレースホルダーテキストでした。これには、position:relative


-1

私も同じ問題を抱えていました。注意深く読んでください:

要素が遷移しているとき、ページ上の残りのテキスト(Webkit内)は、遷移が完了するまでレンダリングをわずかに変更する傾向があることに気付きました。

上記の解決策はどれもうまくいかなかったようです。ただし、設定(のようなもの)

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

アニメーションがある要素で機能しました。

アニメーション化された要素をGPUレイヤーに移動することで、ページレンダリングの通常のフローからそれを削除します(たとえば、z-indexのようなものも機能しなくなります)。副作用として、アニメーションとページの残りの部分は相互に影響を与えなくなります。

もちろん、フォントのレンダリングに影響する場合は、アニメーション化された要素に対してのみ影響します。Chromeに違いはありません。


私は正直に立っています。translateZ(0)が適用されていない場所でも、ページの残りの部分でフォントレンダリングに変更が見られます。
commonpike 2014

フォントアイコンがぼやけていたときに、これが私のために働いた唯一のことです。アニメーション化されていたセクションに変換を適用し、問題を解決しました。
ビル

おい、これはすでに2年前に答えられました。真上...まったく同じ答え/コード。
NiCk Newman 2015

はい、私の唯一のポイントは、あなたが配置する必要がありました-webkit-transform上でアニメーションを持つ要素のレンダリングの変更を防止するために、ページ上の他の要素にします。しかし、コメントしたように、それはしばらくの間機能し、後でページのビットを変更したときに機能しなくなりました。
commonpike 2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.