Hiệu ứng chuyển tiếp CSS làm cho hình ảnh mờ / di chuyển hình ảnh 1px, trong Chrome?


150

Tôi có một số CSS mà khi di chuột, hiệu ứng chuyển tiếp CSS sẽ di chuyển div.

Vấn đề, như bạn có thể thấy trong ví dụ, là translate quá trình chuyển đổi có tác dụng phụ khủng khiếp là làm cho hình ảnh trong div di chuyển xuống 1px xuống / phải (và có thể thay đổi kích thước từng chút một?) Để nó xuất hiện không đúng chỗ và mất tập trung...

Trục trặc dường như áp dụng toàn bộ thời gian hiệu ứng di chuột được áp dụng, và từ quá trình thử và lỗi tôi có thể nói rằng dường như chỉ xảy ra khi chuyển đổi dịch chuyển div (bóng hộp và độ mờ cũng được áp dụng nhưng không có sự khác biệt đối với lỗi khi gỡ bỏ).

Vấn đề dường như chỉ xảy ra khi trang có thanh cuộn. Vì vậy, ví dụ chỉ với một phiên bản của div là ổn, nhưng một lần nữa các div giống hệt được thêm vào và do đó trang yêu cầu một thanh cuộn, vấn đề lại xuất hiện ...


1
Tôi đang dùng Chrome 27 trên OSX và nó vẫn ổn. Tôi tin rằng khi nội dung được đưa vào một lớp, nó sẽ được chuyển thành bitmap trong hình ảnh động và trên các phiên bản cũ hơn / card đồ họa cũ hơn, điều này trông không tuyệt lắm. Hãy thử một phiên bản mới hơn và xem nếu nó đã được sửa.
Rich Bradshaw

Mọi thứ đều ổn trên Chrome 25 OS X. BTW: Tôi muốn đề xuất một cách tiếp cận khác cho kết cấu độ dốc nền so với hình ảnh 300KB!
Paolo

Và cảm ơn @Paolo - hình nền chỉ dành cho trình diễn, nó không phải là hình ảnh được sử dụng trên trang web thực tế!
Lewis

2
Vấn đề phát sinh khi hình ảnh động được xử lý bởi GPU, có vẻ như các vòng bitmap bị tắt một chút. Được sao chép trong Canary, nhưng nó hoạt động tốt nếu bạn tắt tăng tốc GPU
vals 17/03/13

Bạn có thể thử giải pháp này từng khung ... stackoverflow.com/a/42256897/1834212
Miguel

Câu trả lời:


247

Cập nhật 2020

  • Nếu bạn gặp vấn đề với hình ảnh mờ, hãy nhớ kiểm tra câu trả lời từ bên dưới, đặc biệt là image-rendering CSS.
  • Để có khả năng tiếp cận thực tiễn tốt nhất và SEO khôn ngoan, bạn có thể thay thế hình nền bằng <img>thẻ bằng thuộc tính CSS phù hợp với đối tượng .

Câu trả lời gốc

Hãy thử điều này trong CSS của bạn :

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

Điều này làm là nó làm cho bộ phận hành xử "nhiều 2D" hơn.

  • Backface được vẽ như một mặc định để cho phép lật mọi thứ với xoay và như vậy. Không cần điều đó nếu bạn chỉ di chuyển sang trái, phải, lên, xuống, chia tỷ lệ hoặc xoay (ngược chiều kim đồng hồ).
  • Dịch trục Z để luôn có giá trị bằng không.
  • Chrome hiện xử lý backface-visibilitytransformkhông có -webkit-tiền tố. Hiện tại tôi không biết điều này ảnh hưởng đến kết xuất trình duyệt khác (FF, IE) như thế nào, vì vậy hãy thận trọng khi sử dụng các phiên bản không có tiền tố.

27
Có thể không giải thích bất cứ điều gì nhưng nó đã giải thích đủ để khắc phục vấn đề này cho tôi.
McNab

@Class Stacker - giải thích gì? Bạn chỉ cần sao chép dán mã vào phần tử có vấn đề của bạn. Btw này hoạt động rất tốt đẹp!
Easwee

1
tôi đề nghị giải pháp này stackoverflow.com/a/42256897/1834212 tôi đang đăng liên kết để tránh trùng lặp
Miguel

1
Ai đó có thể xác nhận nếu điều này vẫn hoạt động không, bởi vì bất cứ khi nào tôi thêm `-webkit-backface-viewer` và -webkit-transform, tôi thực sự không thể thấy một sự thay đổi và khi tôi mở bảng điều khiển dành cho nhà phát triển. Tôi thấy 2 thuộc tính css đó được vuốt qua, như thể chúng bị ghi đè, nhưng chúng không (css và html trống). Như thể chrome không còn chấp nhận chúng nữa.
Kevin M

1
@KevinM thử mà không có tiền tố -webkit-, đây là CSS chuẩn.
sampoh

91

Bạn cần áp dụng biến đổi 3d cho phần tử, vì vậy nó sẽ có được lớp tổng hợp của riêng nó. Ví dụ:

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

hoặc là

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

Tìm hiểu thêm về tiêu chí tạo lớp bạn có thể đọc ngay tại đây: Kết xuất được tăng tốc trong Chrome


Một lời giải thích:

Ví dụ (hộp xanh di chuột):

Khi bạn sử dụng bất kỳ chuyển đổi nào trên phần tử của mình, nó khiến trình duyệt tính toán lại các kiểu, sau đó bố trí lại nội dung của bạn ngay cả khi thuộc tính chuyển đổi là trực quan (trong ví dụ của tôi, đó là độ mờ đục) và hoàn thiện phần tử:

ảnh chụp màn hình

Vấn đề ở đây là bố cục lại nội dung có thể tạo ra hiệu ứng của các yếu tố "nhảy múa" hoặc "nhấp nháy" trên trang trong khi quá trình chuyển đổi xảy ra. Nếu bạn sẽ đi đến cài đặt, hãy chọn hộp kiểm "Hiển thị các lớp tổng hợp" và sau đó áp dụng chuyển đổi 3d cho một phần tử, bạn sẽ thấy rằng đó là lớp của chính nó được viền với viền màu cam.

ảnh chụp màn hình

Sau khi phần tử có lớp riêng, trình duyệt chỉ cần các lớp tổng hợp khi chuyển đổi mà không bố trí lại hoặc thậm chí các thao tác vẽ nên vấn đề phải được giải quyết:

ảnh chụp màn hình


dụng cụ tốt! có một nguyên nhân điểm của câu trả lời của bạn chi tiết như thế nào! phần mềm nào bạn sử dụng để chụp / mũi tên màn hình?
kroe

Phát hiện ra bạn đời !! Cứu tôi rất nhiều rắc rối ở đó.

Điều này đã lừa tôi. Lúc đầu, tôi đang sử dụng translZ trên cha mẹ mà tôi đang tạo hiệu ứng, nhưng các họa tiết hình nền bên trong vẫn mờ. Tôi đang sử dụng Velocity.js để mở rộng một vùng chứa khác trong đó và áp dụng một cái gì đó như translateZ: 0.000001(một số vô hạn #) và voila! Hình nền sắc nét một lần nữa!
notacouch

Cảm ơn bạn đời. Điều này làm việc về vấn đề của tôi. Nhân tiện, vấn đề của tôi là tôi có một yếu tố được xoay 90 độ và có sự chuyển tiếp mờ dần bằng cách sử dụng độ mờ. khi kích hoạt quá trình chuyển đổi, nội dung của phần tử sẽ di chuyển 1px từ trái sang.
Lloyd aaron

42

Có cùng một vấn đề với iframe youtube được nhúng (Bản dịch được sử dụng để định tâm phần tử iframe). Không có giải pháp nào ở trên hoạt động cho đến khi thử đặt lại bộ lọc css và phép thuật đã xảy ra.

Kết cấu:

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

Phong cách [trước]

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

Phong cách [sau]

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

9
filter: blur(0)đã làm điều đó cho tôi!
Nick

3
Không thể tin được O_o WTF với mờ? Tại sao nó được mặc định?
Yuriy Polarzhayev

Đây là giải pháp cho tôi quá. Câu trả lời được chấp nhận có thể hoạt động cho những người không sử dụng các chức năng "dịch" khác trong các thuộc tính biến đổi của họ, nhưng nó không hoạt động đối với tôi.
Edward Coyle Jr.

Không nên -webkit-tiền tố đến trước? Thông tin thêm
Trevor Nestman

32

Tôi đã đề xuất một CSS thuộc tính mới thử nghiệm mà tôi đã thử nghiệm trên trình duyệt mới nhất và nó tốt:

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

Với điều này, trình duyệt sẽ biết thuật toán kết xuất


Điều này đã sửa các hình ảnh bị mờ của tôi trong khi nhìn thấy mặt sau, mờ (0), translateZ không hoạt động với tôi. Cảm ơn bạn.
Louis Ameline

Đã sửa hình ảnh trong một số trường hợp sử dụng, làm cho nó tồi tệ hơn ở một số trường hợp khác :-) Thú vị trong mọi trường hợp!
Simon Steinberger

Tìm hiểu sâu hơn: image-rendering: -webkit-optimize-contrast;giải quyết vấn đề trên Chrome. Tuy nhiên, hình ảnh trên các trình duyệt khác, ví dụ Firefox, được hiển thị nhiều, tệ hơn nhiều với tùy chọn kết xuất được đặt. Do đó, tôi chỉ sử dụng chỉ thị WebKit, cũng hoạt động trên công cụ Blink. Cảm ơn!
Simon Steinberger

Trong một số trường hợp, nó làm cho hình ảnh bị lởm chởm đáng chú ý. Dường như không thể tìm thấy một điểm ngọt ngào giữa kết quả mờ ảo và điều này ~ thở dài ~
bigp

4

Chỉ tìm thấy một lý do tại sao một yếu tố bị mờ khi được chuyển đổi. tôi đang sử dụngtransform: translate3d(-5.5px, -18px, 0); để định vị lại một phần tử khi nó đã được tải vào, tuy nhiên phần tử đó trở nên mờ.

Tôi đã thử tất cả các đề xuất ở trên nhưng hóa ra là do tôi sử dụng giá trị thập phân cho một trong các giá trị dịch. Các số nguyên không gây ra mờ, và càng đi xa khỏi số thì càng mờ càng tệ.

tức là 5.5pxlàm mờ phần tử nhiều nhất,5.1px ít nhất.

Chỉ cần nghĩ rằng tôi sẽ tặc lưỡi ở đây trong trường hợp nó giúp được bất cứ ai.


Cảm ơn, đây là vấn đề trong trường hợp của tôi - Tôi đã sử dụng translY (-50%) mà phải được đánh giá theo giá trị pixel thập phân.
b4tch

3

Tôi đã gian lận vấn đề bằng cách sử dụng chuyển đổi theo các bước, không suôn sẻ

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

Nó không phải là một giải pháp, nó là một gian lận và không thể được áp dụng ở mọi nơi.

Tôi không thể giải thích nó, nhưng nó làm việc cho tôi. Không có câu trả lời nào khác giúp tôi (OSX, Chrome 63, màn hình không Retina).

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


Trong câu đố của bạn đang run rẩy như Parkinson, nhưng trong trường hợp của tôi đã làm việc.
Tárcio Zemel

2

Thu nhỏ lại gấp đôi và giảm xuống một nửa với zoomcông việc cho tôi.

transform: scale(2);
zoom: 0.5;

điều này dường như làm việc trong chrome cho hình ảnh. Thật không may, nó cũng sửa đổi bất kỳ html nào bạn đặt nó xung quanh quá.
Jack Davidson

2

Tôi đã thử khoảng 10 giải pháp có thể. Trộn chúng lại và chúng vẫn không hoạt động chính xác. Luôn có rung 1px ở cuối.

Tôi tìm giải pháp bằng cách giảm thời gian chuyển tiếp trên bộ lọc.

Điều này đã không làm việc:

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

Giải pháp:

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

Hãy thử điều này trong fiddle:

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

Tôi hi vọng điêu nay se giup được ai đo.


1

Thử filter: blur(0);

Nó làm việc cho tôi


Tôi cũng làm việc cho tôi, Chrome 63, 64 và Vivaldi 1.13
GTCrais

1

Đối với tôi, bây giờ là năm 2018. Điều duy nhất khắc phục vấn đề của tôi (một dòng nhấp nháy màu trắng chạy qua hình ảnh trên di chuột) là áp dụng điều này cho thành phần liên kết của tôi giữ thành phần hình ảnh có 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;
}

Đúng! 'Blur (0)' sửa nó cho tôi trong Chrome. Mặc dù làm cho hình ảnh hơi mờ khi thay đổi kích thước nhưng ít gây chú ý hơn so với bước nhảy / thay đổi kích thước
00-BBB

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

Tôi đã được giúp đỡ bằng cách đặt giá trị của các bước thời gian .3schuyển đổi bằng nhau.3s


-7

Chỉ có vấn đề tương tự. Cố gắng đặt vị trí: liên quan đến yếu tố cha mẹ, điều đó làm việc cho tôi.


5
Bạn có một bản demo của công việc này? Tôi không biết làm thế nào điều này sẽ giúp
Zach Saucier

2
Nếu bạn có thể vui lòng chỉnh sửa câu trả lời của mình và giải thích mã bạn đang hiển thị là gì và tại sao / làm thế nào mã đó trả lời câu hỏi, nó thực sự có thể giúp ích. Các khối mã tự chúng thường không phải là câu trả lời hữu ích.
Lea Cohen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.