CSSトランジション効果により、Chromeで画像がぼやける/画像が1ピクセル移動する?


150

ホバー時にCSSトランジションエフェクトがdivを移動するCSSがあります。

この例でわかるように、translateトランジションには、div内の画像を1px右/下に移動させる(そして、サイズを少しだけ変更する可能性があります)という、ひどい副作用があり、場違いに見えて、焦点が合っていない...

グリッチはホバー効果が適用されている間ずっと適用されているようであり、試行錯誤のプロセスから、私は安全に、トランジショントランジションがdivを移動するときにのみ発生するように見える(ボックスの影と不透明度も適用されますが、違いはありません)削除時のエラー)。

この問題は、ページにスクロールバーがある場合にのみ発生するようです。したがって、divのインスタンスが1つしかない例でも問題ありませんが、同じdivが追加され、ページにスクロールバーが必要になるため、問題が再び発生します...


1
私はOSXのChrome 27を使用していますが、問題ありません。コンテンツがレイヤーに入れられると、アニメーション中にビットマップに変換され、古いバージョン/古いグラフィックスカードではこれは見栄えが悪いと思います。新しいバージョンを試して、修正されているかどうかを確認してください。
リッチブラッドショー

Chrome 25 OS Xではすべて問題ありません。ところで、背景のグラデーションテクスチャには、300KBの画像とは異なるアプローチをお勧めします。
Paolo

@Paoloに感謝-背景画像はデモ用であり、実際のサイトで使用されている画像ではありません。
ルイス

2
この問題は、アニメーションがGPUで処理されるときに発生し、ビットマップの丸めが少しずれているように見えます。Canaryで再現されていますが、GPUアクセラレーションをオフにしても問題ありません
vals

フレームごとにこのソリューションを試すことができます... stackoverflow.com/a/42256897/1834212
Miguel

回答:


247

2020年の更新

  • 画像がぼやけている場合は、下からの回答、特にimage-renderingCSSプロパティも確認してください。
  • ベストプラクティスのアクセシビリティとSEOに関しては、object-fit CSSプロパティ<img>を使用して背景画像をタグに置き換えることができます。

元の答え

CSSでこれを試してください:

.your-class-name {
    /* ... */
    -webkit-backface-visibility: hidden;
    -webkit-transform: translateZ(0) scale(1.0, 1.0);
}

これにより、部門が「より2Dで」動作するようになります。

  • 裏面はデフォルトで描かれ、回転などで物事をめくることができます。左、右、上、下、スケール、または時計回りに(反時計回りに)回転するだけの場合、その必要はありません。
  • Z軸を変換して、常にゼロの値を設定します。
  • Chrome は接頭辞なしで処理されるようにbackface-visibilityなりました。現在、これが他のブラウザーのレンダリングにどのように影響するかわかりません(FF、IE)。プレフィックスのないバージョンを使用する場合は注意が必要です。transform-webkit-

27
何も説明しなかったかもしれませんが、この問題を修正するのに十分な説明がありました。
McNab 2013年

@Class Stacker-何を説明しますか?問題のある要素にコードをコピーして貼り付けるだけです。ところでこれはとてもうまくいきます!
easwee 2013

1
私は、このソリューションの提案stackoverflow.com/a/42256897/1834212の回避重複へのリンク掲載イム
ミゲル

1
`-webkit-backface-visibility`とを追加すると-webkit-transform、変更が実際に表示されず、Chrome開発者コンソールを開いたときに、誰かがこれがまだ機能するかどうかを確認できますか?それらの2つのcssプロパティが上書きされたかのようにストロークされていますが、上書きされていません(空のcssおよびhtml)。まるでchromeがそれらを受け入れないかのようです。
Kevin M

1
@ webkit-接頭辞なしで@KevinMを試してください。これらは現在標準のCSSです。
サンポー2017年

91

要素に3D変換を適用して、独自の複合レイヤーを取得する必要があります。例えば:

.element{
    -webkit-transform: translateZ(0);
    transform: translateZ(0);
}

または

.element{
    -webkit-transform: translate3d(0,0,0);
    transform: translate3d(0,0,0);
}

ここで読むことができるレイヤー作成基準の詳細:Chromeでの高速レンダリング


説明:

例(緑色のボックスをホバー):

エレメントでトランジションを使用すると、ブラウザーがスタイルを再計算し、トランジションプロパティが視覚的(例では不透明)であってもコンテンツを再レイアウトし、最終的にエレメントをペイントします。

スクリーンショット

ここでの問題は、遷移が発生している間、ページ上の要素を「ダンス」または「点滅」させる効果をもたらす可能性があるコンテンツの再レイアウトです。設定に移動し、「複合レイヤーを表示」チェックボックスをオンにして、要素に3D変換を適用すると、オレンジ色の境界線で囲まれた独自のレイヤーが表示されます。

スクリーンショット

要素が独自のレイヤーを取得した後、ブラウザーは遷移時にレイヤーを合成するだけで、再レイアウトやペイント操作は必要ないため、問題を解決する必要があります。

スクリーンショット


いい従業員!あなたの答えがいかに詳細であるかについての主な原因を得ました!画面キャプチャ/矢印に使用しているソフトウェアはどれですか?
クロー

メイトにスポット!面倒な作業をたくさん省いてくれました。

これは私にとってはトリックでした。最初は、アニメーションする親でtranslateZを使用していましたが、内部の背景画像のスプライトはまだぼやけていました。私はVelocity.jsを使用してその中のさらに別のコンテナーをスケーリングし、translateZ: 0.000001(いくつかの無限小の#)のようなものを適用しています!シャープな背景画像をもう一度!
notacouch 2015年

どうも。これは私の問題を解決しました。ちなみに、私の問題は、90度回転した要素があり、不透明度を使用してフェードイントランジションがあることです。遷移をトリガーすると、要素のコンテンツが左から1px移動します。
ロイドアーロン2016

42

埋め込まれたyoutube iframeで同じ問題がありました(翻訳はiframe要素の中央揃えに使用されました)。上記の解決策は、cssフィルターのリセットを試行して魔法が発生するまで機能しませんでした。

構造:

<div class="translate">
     <iframe/>
</div>

スタイル[前]

.translate {
  transform: translateX(-50%);
  -webkit-transform: translateX(-50%);
}

スタイル[後]

.translate {
  transform: translateX(-50%);
  -webkit-transform: translateX(-50%);
  filter: blur(0);
  -webkit-filter: blur(0);
}

9
filter: blur(0)私のためにやった!
Nick

3
ぼやけた信じられないほどのO_o WTF?なぜデフォルトでオンになっているのですか?
Yuriy Polezhayev

これも私の解決策でした。受け入れられた回答は、変換プロパティで他の「変換」関数を使用していない人には有効ですが、私には有効ではありませんでした。
Edward Coyle Jr.

-webkit-接頭辞は前に来るべきではありませんか?詳細
Trevor Nestman、2017年

32

私は最新のブラウザでテストした実験的な新しい属性CSSをお勧めしました。

image-rendering: optimizeSpeed;             /*                     */
image-rendering: -moz-crisp-edges;          /* Firefox             */
image-rendering: -o-crisp-edges;            /* Opera               */
image-rendering: -webkit-optimize-contrast; /* Chrome (and Safari) */
image-rendering: optimize-contrast;         /* CSS3 Proposed       */
-ms-interpolation-mode: nearest-neighbor;   /* IE8+                */

これにより、ブラウザはレンダリングのアルゴリズムを認識します


これにより、ぼやけて回転した画像が修正されましたが、裏面表示、blur(0)、translateZが機能しませんでした。ありがとうございました。
Louis Ameline、2015

いくつかのユースケースで画像を修正し、他のいくつかのケースではそれをひどく悪化させました:-)どんな場合でも興味深い!
Simon Steinberger、

より深く掘り下げて:image-rendering: -webkit-optimize-contrast;Chromeの問題を解決します。ただし、Firefoxなどの他のブラウザーの画像は、レンダリングオプションを設定すると、かなりレンダリングされます。したがって、Blinkエンジンでも機能するWebKitディレクティブのみを使用します。ありがとう!
Simon Steinberger

場合によっては、画像が著しくギザギザになることがあります。ぼやけ結果の間でスイートスポットと〜ため息〜この1見つけることができないよう
bigp

4

変換時に要素がぼやける別の理由を見つけました。transform: translate3d(-5.5px, -18px, 0);読み込まれた要素を再配置するために使用していたが、その要素がぼやけた。

上記の提案をすべて試しましたが、変換値の1つに10進数値を使用したことが原因であることがわかりました。整数ではぼかしは発生しません。整数から離れるほどぼかしは悪化しました。

つまり5.5px、要素を最もぼかし5.1pxます。

誰かを助けるために、ここでこれをチャックすると思いました。


おかげで、これは私の場合の問題でした-10進ピクセル値に評価されているに違いないtranslateY(-50%)を使用していました。
b4tch

3

私はスムーズではなく、段階的な移行を使用して問題をだました

transition-timing-function: steps(10, end);

それは解決策ではなく、不正行為であり、どこにでも適用することはできません。

説明はできませんが、私にとってはうまくいきます。他の答えはどれも役に立ちません(OSX、Chrome 63、非Retinaディスプレイ)。

https://jsfiddle.net/tuzae6a9/6/


あなたのバイオリンはパーキンソン病のように揺れていますが、私の場合はうまくいきました。
TárcioZemel


2

私は約10の可能性のある解決策を試しました。それらを混同しても、それらはまだ正しく機能しませんでした。最後に常に1pxの揺れがありました。

フィルターの遷移時間を減らすことで解決策を見つけます。

これはうまくいきませんでした:

.elem {
  filter: blur(0);
  transition: filter 1.2s ease;
}
.elem:hover {
  filter: blur(7px);
}

解決:

.elem {
  filter: blur(0);
  transition: filter .7s ease;
}
.elem:hover {
  filter: blur(7px);
}

フィドルでこれを試してください:

.blur {
  border: none;
  outline: none;
  width: 100px; height: 100px;
  background: #f0f;
  margin: 30px;
  -webkit-filter: blur(10px);
  transition: all .7s ease-out;
  /* transition: all .2s ease-out; */
}
.blur:hover {
  -webkit-filter: blur(0);
}

.blur2 {
  border: none;
  outline: none;
  width: 100px; height: 100px;
  background: tomato;
  margin: 30px;
  -webkit-filter: blur(10px);
  transition: all .2s ease-out;
}
.blur2:hover {
  -webkit-filter: blur(0);
}
<div class="blur"></div>

<div class="blur2"></div>

これが誰かの役に立つことを願っています。



1

私にとっては、2018年になりました。私の問題(ホバー上の画像を通る白いグリッチーフリッカーライン)を修正した唯一のことは、これを、 transform: scale(1.05)

a {
   -webkit-backface-visibility: hidden;
   backface-visibility: hidden;
   -webkit-transform: translateZ(0) scale(1.0, 1.0);
   transform: translateZ(0) scale(1.0, 1.0);
   -webkit-filter: blur(0);
   filter: blur(0);
}
a > .imageElement {
   transition: transform 3s ease-in-out;
}

はい!'blur(0)'はChromeでそれを修正します。サイズを変更しても画像がわずかにぼやけますが、ジャンプ/サイズ変更ほど目立ちません
00-BBB

0
filter: blur(0)
transition: filter .3s ease-out
transition-timing-function: steps(3, end) // add this string with steps equal duration

遷移時間の.3s値を遷移タイミングのステップに等しく設定することで助けられました.3s


-7

同じ問題が発生しました。親要素に対してposition:relativeを設定してみてください、それは私のために働きました。


5
この動作のデモはありますか?私はこれがどのように役立つか分かりません
Zach Saucier '11 / 11/9

2
回答を編集して、表示しているコードが何をするのか、そのコードが質問になぜ/どのように回答するのかを説明していただければ、非常に役立ちます。それ自体のコードブロックは、通常は有用な回答ではありません。
Lea Cohen、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.