Efek transisi CSS membuat gambar buram / memindahkan gambar 1px, di Chrome?

150

Saya punya beberapa CSS yang di hover, efek transisi CSS akan menggerakkan div.

Masalahnya, seperti yang Anda lihat dalam contoh, adalah bahwa translatetransisi memiliki efek samping yang mengerikan dari membuat gambar dalam div bergerak dengan 1px ke bawah / kanan (dan mungkin mengubah ukuran sedikit sekali?) Sehingga tampak tidak pada tempatnya dan tidak fokus...

Kesalahan tampaknya berlaku sepanjang waktu efek hover diterapkan, dan dari proses coba-coba saya dapat dengan aman mengatakan hanya tampaknya terjadi ketika transisi translate memindahkan div (bayangan kotak dan opacity juga diterapkan tetapi tidak ada bedanya untuk kesalahan saat dihapus).

Masalahnya hanya terjadi ketika halaman memiliki scrollbar. Jadi contoh dengan hanya satu contoh div baik-baik saja, tetapi sekali lagi div identik diidentifikasi dan karena itu halaman memerlukan scrollbar masalah muncul lagi ...

Lewis
sumber
1
Saya menggunakan Chrome 27 di OSX, dan tidak masalah. Saya percaya bahwa ketika konten dimasukkan ke dalam lapisan itu akan berubah menjadi bitmap selama animasi, dan bahwa pada versi yang lebih lama / kartu grafis yang lebih tua ini tidak terlihat bagus. Coba versi yang lebih baru dan lihat apakah sudah diperbaiki.
Rich Bradshaw
Semuanya baik-baik saja di Chrome 25 OS X. BTW: Saya menyarankan pendekatan berbeda untuk tekstur gradien latar belakang daripada gambar 300KB!
Paolo
Dan terima kasih @ Paolo - gambar latar belakang hanya untuk demonstrasi, bukan gambar yang digunakan di situs sebenarnya!
Lewis
2
Masalah muncul ketika animasi ditangani oleh GPU, sepertinya pembulatan bitmap sedikit mati. Direproduksi dalam Canary, tetapi berfungsi dengan baik jika Anda mematikan akselerasi GPU
vai
Anda dapat mencoba solusi ini setiap frame ... stackoverflow.com/a/42256897/1834212
Miguel

Jawaban:

247

Pembaruan tahun 2020

  • Jika Anda memiliki masalah dengan gambar buram, pastikan untuk memeriksa jawaban dari bawah juga, terutama image-renderingproperti CSS.
  • Untuk aksesibilitas praktik terbaik dan SEO, Anda dapat mengganti gambar latar belakang dengan <img>tag menggunakan properti CSS sesuai objek .

Jawaban asli

Coba ini di CSS Anda :

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

Apa yang dilakukan adalah membuat divisi berperilaku "lebih 2D".

  • Backface digambar sebagai default untuk memungkinkan membalik benda dengan rotate dan semacamnya. Tidak perlu jika Anda hanya bergerak ke kiri, kanan, atas, bawah, skala atau putar (berlawanan arah jarum jam).
  • Menerjemahkan sumbu Z untuk selalu memiliki nilai nol.
  • Chrome sekarang menangani backface-visibilitydan transformtanpa -webkit-awalan. Saat ini saya tidak tahu bagaimana ini mempengaruhi rendering browser lain (FF, IE), jadi gunakan versi yang tidak diawali dengan hati-hati.
sampoh
sumber
27
Mungkin tidak menjelaskan apa-apa tetapi cukup menjelaskan untuk memperbaiki masalah ini untuk saya.
McNab
@Class Stacker - apa yang harus dijelaskan? Anda cukup menyalin tempel kode ke elemen bermasalah Anda. Tapi ini bekerja sangat bagus!
easwee
1
saya sarankan solusi ini stackoverflow.com/a/42256897/1834212 saya memposting tautan untuk menghindari duplikasi
Miguel
1
Dapatkah seseorang mengonfirmasi jika ini masih berfungsi, karena setiap kali saya menambahkan `-webkit-backface-visibilitas` dan -webkit-transform, saya tidak bisa melihat perubahan, dan ketika saya membuka konsol pengembang chrome. Saya melihat 2 properti css itu dibelai, seolah-olah mereka ditimpa, tetapi tidak (kosongkan css dan html). Seolah chrome tidak lagi menerimanya.
Kevin M
1
@KevinM mencoba tanpa awalan -webkit-, ini adalah CSS standar.
sampoh
91

Anda perlu menerapkan transformasi 3d ke elemen, sehingga akan mendapatkan lapisan kompositnya sendiri. Misalnya:

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

atau

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

Lebih lanjut tentang kriteria pembuatan lapisan, Anda dapat membaca di sini: rendering yang dipercepat di Chrome


Sebuah penjelasan:

Contoh (arahkan kotak hijau):

Ketika Anda menggunakan transisi apa pun pada elemen Anda itu menyebabkan browser untuk menghitung ulang gaya, kemudian tata ulang konten Anda bahkan jika properti transisi adalah visual (dalam contoh saya itu adalah opacity) dan akhirnya cat elemen:

tangkapan layar

Masalahnya di sini adalah tata letak ulang konten yang dapat membuat efek elemen "menari" atau "berkedip" pada halaman saat transisi terjadi. Jika Anda akan pergi ke pengaturan, centang kotak "Tampilkan lapisan komposit" dan kemudian menerapkan transformasi 3d ke elemen, Anda akan melihat bahwa itu mendapatkan lapisan itu sendiri yang diuraikan dengan batas oranye.

tangkapan layar

Setelah elemen mendapatkan lapisannya sendiri, browser hanya perlu lapisan komposit pada transisi tanpa tata letak ulang atau bahkan operasi cat sehingga masalah harus dipecahkan:

tangkapan layar

sol0mka
sumber
barang bagus! Ada alasan mengapa seberapa rinci jawaban Anda! perangkat lunak apa yang Anda gunakan untuk menangkap layar / panah?
kroe
Temukan pasangan !! Menyelamatkan saya banyak kerumitan di sana.
Ini berhasil bagi saya. Pada awalnya saya menggunakan translateZ pada orang tua yang saya animasikan, tetapi sprite gambar latar di dalamnya masih buram. Saya menggunakan Velocity.js untuk skala wadah lain di dalamnya dan menerapkan sesuatu seperti translateZ: 0.000001(beberapa # sangat kecil) dan voila! Tajam gambar latar belakang sekali lagi!
notacouch
Terima kasih sobat. Ini berhasil pada masalah saya. omong-omong, masalah saya adalah saya memiliki elemen yang diputar 90 derajat dan memiliki transisi fade-in menggunakan opacity. ketika memicu transisi konten elemen bergerak 1px dari kiri.
Lloyd aaron
42

Punya masalah yang sama dengan iframe youtube embeded (Terjemahan digunakan untuk memusatkan elemen iframe). Tak satu pun dari solusi di atas bekerja sampai mencoba mengatur ulang filter css dan keajaiban terjadi.

Struktur:

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

Gaya [sebelum]

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

Gaya [setelah]

.translate {
  transform: translateX(-50%);
  -webkit-transform: translateX(-50%);
  filter: blur(0);
  -webkit-filter: blur(0);
}
xb1itz
sumber
9
filter: blur(0)melakukannya untukku!
Nick
3
O_o WTF yang luar biasa dengan blur? Mengapa diaktifkan secara default?
Yuriy Polezhayev
Ini juga solusi bagi saya. Jawaban yang diterima bisa berfungsi untuk orang yang tidak menggunakan fungsi "terjemahkan" lainnya dalam properti transformasi mereka, tetapi itu tidak berfungsi untuk saya.
Edward Coyle Jr.
Bukankah seharusnya -webkit-awalan datang sebelumnya? Info Lebih Lanjut
Trevor Nestman
32

Saya merekomendasikan CSS atribut baru eksperimental yang saya uji pada browser terbaru dan bagus:

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

Dengan ini browser akan mengetahui algoritma untuk rendering

Felipez
sumber
Ini memperbaiki gambar yang diputar kabur saya dengan visibilitas backface, blur (0), translateZ tidak bekerja untuk saya. Terima kasih.
Louis Ameline
Memperbaiki gambar dalam beberapa kasus penggunaan, membuatnya lebih buruk dalam beberapa kasus lain :-) Menarik dalam hal apa pun!
Simon Steinberger 2-15
Digali lebih dalam: image-rendering: -webkit-optimize-contrast;menyelesaikan masalah di Chrome. Namun, gambar di browser lain, misalnya Firefox, mendapatkan rendering lebih, jauh lebih buruk dengan set opsi rendering. Karena itu, saya hanya menggunakan arahan WebKit, yang juga berfungsi pada mesin Blink. Terima kasih!
Simon Steinberger 2-15
Dalam beberapa kasus ini menyebabkan gambar terlihat jaggy. Sepertinya tidak bisa menemukan titik manis di antara hasil blurrier dan yang satu ini ~ sigh ~
bigp
4

Baru saja menemukan alasan lain mengapa suatu elemen menjadi buram ketika diubah. Saya menggunakan transform: translate3d(-5.5px, -18px, 0);untuk memposisikan ulang elemen setelah elemen dimuat, namun elemen itu menjadi buram.

Saya mencoba semua saran di atas tetapi ternyata itu karena saya menggunakan nilai desimal untuk salah satu nilai terjemahan. Seluruh angka tidak menyebabkan keburaman, dan semakin jauh saya pergi dari seluruh nomor semakin buruk menjadi kabur.

yaitu 5.5pxmengaburkan elemen paling banyak, paling 5.1pxsedikit.

Hanya berpikir saya akan membuang ini di sini kalau-kalau itu membantu siapa pun.

ashrobbins
sumber
Terima kasih, ini adalah masalah dalam kasus saya - saya menggunakan translateY (-50%) yang pasti telah dievaluasi ke nilai piksel desimal.
b4tch
3

Saya menipu masalah menggunakan transisi dengan langkah-langkah, tidak lancar

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

Ini bukan penyelesaian, itu curang dan tidak bisa diterapkan di mana-mana.

Saya tidak bisa menjelaskannya, tetapi itu berhasil untuk saya. Tidak ada jawaban lain yang membantu saya (OSX, Chrome 63, tampilan Non-Retina).

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

Evgeny Gendel
sumber
Dalam biola Anda gemetar seperti Parkinson, tetapi dalam kasus saya berhasil.
Tárcio Zemel
2

Menskala untuk menggandakan dan menurunkan hingga setengah dengan zoomberhasil bagi saya.

transform: scale(2);
zoom: 0.5;
Kushagra Gour
sumber
ini sepertinya berfungsi di chrome untuk gambar. sayangnya itu juga memodifikasi html yang Anda masukkan juga.
Jack Davidson
2

Saya sudah mencoba sekitar 10 kemungkinan solusi. Menggabungkan mereka dan mereka masih tidak berfungsi dengan benar. Selalu ada shake 1px di akhir.

Saya menemukan solusi dengan mengurangi waktu transisi pada filter.

Ini tidak berhasil:

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

Larutan:

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

Coba ini di biola:

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

Saya harap ini membantu seseorang.

Adam Orlov
sumber
1

Mencoba filter: blur(0);

Ini berhasil untuk saya

Fred K
sumber
Bekerja untuk saya juga, Chrome 63, 64, dan Vivaldi 1.13
GTCrais
1

Bagi saya, sekarang pada tahun 2018. Satu-satunya hal yang memperbaiki masalah saya (garis glicky-flicker putih yang berjalan melalui gambar di hover) menerapkan ini ke elemen tautan saya yang memegang elemen gambar yang memiliki 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;
}
mateostabio
sumber
Iya! 'blur (0)' memperbaikinya untuk saya di Chrome. Membuat gambar sangat sedikit buram pada pengubahan ukuran tetapi kurang terlihat daripada lompatan / pengubahan ukuran
00-BBB
0
filter: blur(0)
transition: filter .3s ease-out
transition-timing-function: steps(3, end) // add this string with steps equal duration

Saya terbantu dengan mengatur nilai durasi .3stransisi sama dengan langkah waktu transisi.3s

j-ketuk
sumber
-7

Baru saja mendapat masalah yang sama. Cobalah untuk mengatur posisi: relatif terhadap elemen induk, yang bekerja untuk saya.

Martin
sumber
5
Apakah Anda memiliki demo ini berfungsi? Saya tidak tahu bagaimana ini akan membantu
Zach Saucier
2
Jika Anda dapat mengedit jawaban Anda dan menjelaskan apa yang kode Anda tampilkan, dan mengapa / bagaimana kode itu menjawab pertanyaan, itu bisa sangat membantu. Blok kode sendiri biasanya bukan jawaban yang berguna.
Lea Cohen