ผลการเปลี่ยนแปลง CSS ทำให้ภาพพร่ามัว / ย้ายภาพ 1px ใน Chrome หรือไม่


150

ฉันมี CSS บางอย่างที่วางเมาส์บนเอฟเฟกต์การเปลี่ยน CSS จะย้าย div

ปัญหาดังที่คุณเห็นในตัวอย่างคือการtranslateเปลี่ยนแปลงมีผลข้างเคียงที่น่ากลัวในการทำให้ภาพในการเลื่อน div เคลื่อนไหวโดย 1px ลง / ขวา (และอาจจะปรับขนาดเล็กน้อยเลยหรือ?) เพื่อให้ปรากฏออกนอกสถานที่และ ออกจากโฟกัส ...

ความผิดพลาดดูเหมือนว่าจะนำมาใช้ตลอดเวลาที่ใช้เอฟเฟกต์โฮเวอร์และจากขั้นตอนการทดลองและข้อผิดพลาดฉันสามารถพูดได้อย่างปลอดภัยเท่านั้นดูเหมือนว่าจะเกิดขึ้นเมื่อการเปลี่ยนแปลย้าย div (เงากล่องและความทึบก็ใช้เช่นกัน ข้อผิดพลาดเมื่อลบออก)

ปัญหาดูเหมือนจะเกิดขึ้นเฉพาะเมื่อเพจนั้นมีแถบเลื่อน ดังนั้นตัวอย่างที่มีเพียงอินสแตนซ์เดียวของ div จึงใช้ได้ แต่เมื่อมีการเพิ่ม div ที่เหมือนกันอีกครั้งและหน้าเว็บต้องการแถบเลื่อนปัญหาจะเกิดขึ้นอีกครั้ง ...


1
ฉันใช้ Chrome 27 บน OSX และก็ใช้ได้ ฉันเชื่อว่าเมื่อเนื้อหาได้รับการเลเยอร์มันจะกลายเป็นบิตแมประหว่างภาพเคลื่อนไหวและบนกราฟิกการ์ดรุ่นเก่า / รุ่นเก่าสิ่งนี้ดูไม่ดีนัก ลองรุ่นที่ใหม่กว่าและดูว่าแก้ไขหรือไม่
แบรดชอว์รวย

ทุกอย่างเรียบร้อยใน Chrome 25 OS X. BTW: ฉันขอแนะนำวิธีที่แตกต่างกันสำหรับพื้นผิวไล่ระดับสีพื้นหลังมากกว่าภาพขนาด 300KB!
เปาโล

และขอขอบคุณ @Paolo - ภาพพื้นหลังใช้สำหรับการสาธิตเท่านั้นไม่ใช่ภาพที่ใช้ในไซต์จริง!
Lewis

2
ปัญหาเกิดขึ้นเมื่อภาพเคลื่อนไหวได้รับการจัดการโดย GPU ดูเหมือนว่าการปัดเศษบิตแมปจะปิดเล็กน้อย ทำซ้ำใน Canary แต่ทำงานได้ดีถ้าคุณปิดการเร่งด้วย GPU
vals

คุณสามารถลองวิธีแก้ปัญหานี้ในแต่ละเฟรม ... stackoverflow.com/a/42256897/1834212
Miguel

คำตอบ:


247

อัพเดตปี 2020

  • หากคุณมีปัญหาเกี่ยวกับภาพที่ไม่ชัดโปรดตรวจสอบคำตอบจากด้านล่างด้วยโดยเฉพาะimage-renderingคุณสมบัติ CSS
  • สำหรับการเข้าถึงการปฏิบัติที่ดีที่สุดและ SEO อย่างชาญฉลาดคุณสามารถแทนที่ภาพพื้นหลังด้วย<img>แท็กโดยใช้คุณสมบัติ CSS ที่พอดีกับวัตถุ

คำตอบเดิม

ลองสิ่งนี้ในCSSของคุณ:

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

สิ่งนี้ทำให้การแบ่งทำงานเป็น "more 2D"

  • Backface ถูกวาดเป็นค่าเริ่มต้นเพื่ออนุญาตให้พลิกสิ่งต่าง ๆ ด้วยการหมุนและเช่น ไม่จำเป็นว่าถ้าคุณเลื่อนไปทางซ้ายขวาขึ้นลงปรับขนาดหรือหมุน (ทวนเข็มนาฬิกา) ตามเข็มนาฬิกา
  • แปลแกน Z เพื่อให้มีค่าเป็นศูนย์เสมอ
  • ตอนนี้ Chrome จัดการbackface-visibilityและtransformไม่มีส่วน-webkit-นำหน้า ขณะนี้ฉันไม่ทราบว่าสิ่งนี้มีผลต่อการแสดงผลเบราว์เซอร์อื่น ๆ (FF, IE) อย่างไรดังนั้นให้ใช้เวอร์ชันที่ไม่มีคำนำหน้าด้วยความระมัดระวัง

27
อาจไม่ได้อธิบายอะไรเลย แต่มันอธิบายได้เพียงพอที่จะแก้ไขปัญหานี้ให้ฉันได้
McNab

@Class Stacker - จะอธิบายยังไงดี? คุณเพียงแค่คัดลอกวางรหัสไปยังองค์ประกอบที่มีปัญหาของคุณ Btw นี้ใช้งานได้ดีมาก!
easwee

1
ฉันขอแนะนำทางออกนี้stackoverflow.com/a/42256897/1834212 ฉันโพสต์ลิงค์เพื่อหลีกเลี่ยงการซ้ำ
มิเกล

1
บางคนสามารถยืนยันได้ว่านี่ยังใช้งานได้หรือไม่เพราะเมื่อใดก็ตามที่ฉันเพิ่ม `-webkit-backface-visible` และ-webkit-transformฉันไม่เห็นการเปลี่ยนแปลงและเมื่อฉันเปิดคอนโซลนักพัฒนาของ Chromes ฉันเห็นคุณสมบัติทั้งสองของ css ถูกลูบผ่านราวกับว่ามันถูกเขียนทับ แต่มันไม่ได้ (css และ html ที่ว่างเปล่า) ราวกับว่าโครเมี่ยมไม่ยอมรับพวกเขาอีกต่อไป
Kevin M

1
@KevinM ลองโดยไม่ใช้ -webkit- คำนำหน้าสิ่งเหล่านี้เป็น CSS มาตรฐาน
sampoh

91

คุณต้องใช้การแปลง 3 มิติกับองค์ประกอบดังนั้นมันจะได้รับชั้นคอมโพสิตของตัวเอง ตัวอย่างเช่น

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

หรือ

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

เพิ่มเติมเกี่ยวกับเกณฑ์การสร้างเลเยอร์ที่คุณสามารถอ่านได้ที่นี่: เร่งการแสดงผลใน Chrome


คำอธิบาย:

ตัวอย่าง (โฮเวอร์กล่องสีเขียว):

เมื่อคุณใช้การเปลี่ยนแปลงใด ๆ ในองค์ประกอบของคุณมันทำให้เบราว์เซอร์เพื่อคำนวณรูปแบบแล้วจัดรูปแบบเนื้อหาของคุณใหม่แม้ว่าคุณสมบัติการเปลี่ยนแปลงเป็นภาพ (ในตัวอย่างของฉันมันเป็นความทึบ) และทาสีองค์ประกอบ:

ภาพหน้าจอ

ปัญหาในที่นี้คือเค้าโครงใหม่ของเนื้อหาที่สามารถสร้างเอฟเฟกต์ "ลีลาศ" หรือ "กระพริบ" บนหน้าเว็บในขณะที่การเปลี่ยนแปลงเกิดขึ้น หากคุณจะไปที่การตั้งค่าให้ทำเครื่องหมายในช่อง "แสดงเลเยอร์คอมโพสิต" แล้วใช้การแปลง 3 มิติกับองค์ประกอบคุณจะเห็นว่ามันได้รับเลเยอร์ของตัวเองซึ่งมีเส้นขอบสีส้ม

ภาพหน้าจอ

หลังจากที่อิลิเมนต์ได้รับเลเยอร์ของตัวเองเบราว์เซอร์จะต้องคอมโพสิตเลเยอร์ในช่วงการเปลี่ยนภาพโดยไม่ต้องจัดวางเลเยอร์ใหม่หรือแม้แต่การดำเนินการทาสีเพื่อแก้ไขปัญหา:

ภาพหน้าจอ


สิ่งที่ดี! ได้จุดสาเหตุของรายละเอียดคำตอบของคุณ! ซอฟต์แวร์ที่คุณใช้สำหรับจับภาพหน้าจอ / ลูกศร?
kroe

จุดบนคู่ !! ช่วยให้ฉันยุ่งยากมากมายที่นั่น

นี้ได้เคล็ดลับสำหรับฉัน. ตอนแรกฉันกำลังใช้ translateZ กับผู้ปกครองที่ฉันเคลื่อนไหว แต่สไปรต์ภาพพื้นหลังภายในยังคงพร่ามัว ฉันใช้ Velocity.js เพื่อขยายขนาดคอนเทนเนอร์อื่นภายในบรรจุและใช้สิ่งที่ต้องการtranslateZ: 0.000001(# ที่เล็กมาก) และ voila! ภาพพื้นหลังคมชัดอีกครั้ง!
notacouch

ขอบคุณเพื่อน สิ่งนี้ใช้ได้กับปัญหาของฉัน โดยวิธีการที่ปัญหาของฉันคือฉันมีองค์ประกอบที่หมุน 90 องศาและมีการเปลี่ยนแปลงจางหายไปโดยใช้ความทึบ เมื่อเรียกการเปลี่ยนแปลงเนื้อหาขององค์ประกอบจะย้าย 1px จากซ้าย
ลอยด์แอรอน

42

มีปัญหาเดียวกันกับ iframe ของ YouTube แบบฝัง (การแปลถูกใช้เพื่อจัดองค์ประกอบของ 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

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

ด้วยสิ่งนี้เบราว์เซอร์จะรู้ว่าอัลกอริทึมสำหรับการแสดงผล


นี่ทำให้ภาพที่หมุนไม่ชัดของฉันในขณะที่การมองเห็นด้านหลังเบลอ (0), translateZ ไม่ทำงานสำหรับฉัน ขอบคุณ.
Louis Ameline

แก้ไขภาพในบางกรณีการใช้งานทำให้แย่ลงอย่างมากในบางกรณี :-) น่าสนใจในทุกกรณี!
Simon Steinberger

ขุดลึก: image-rendering: -webkit-optimize-contrast;แก้ปัญหาบน Chrome อย่างไรก็ตามรูปภาพในเบราว์เซอร์อื่น ๆ เช่น Firefox จะเรนเดอร์มากยิ่งแย่ลงมากเมื่อตั้งค่าตัวเลือกการแสดงผล ดังนั้นฉันจะใช้คำสั่ง WebKit เท่านั้นซึ่งทำงานกับเอ็นจิ้น Blink ขอบคุณ!
Simon Steinberger

ในบางกรณีมันทำให้ภาพสั่นอย่างเห็นได้ชัด ดูเหมือนจะไม่พบจุดหวานในระหว่างผลลัพธ์ blurrier และอันนี้ ~ ถอนหายใจ ~
bigp

4

เพิ่งค้นพบอีกเหตุผลหนึ่งว่าทำไมองค์ประกอบจึงพร่ามัวเมื่อถูกแปลงสภาพ ฉันใช้transform: translate3d(-5.5px, -18px, 0);เพื่อจัดตำแหน่งองค์ประกอบอีกครั้งเมื่อมันถูกโหลดเข้าไป แต่องค์ประกอบนั้นก็พร่ามัว

ฉันลองใช้คำแนะนำทั้งหมดข้างต้น แต่ปรากฎว่าเป็นเพราะฉันใช้ค่าทศนิยมสำหรับหนึ่งในค่าการแปล จำนวนทั้งหมดไม่ทำให้เกิดความพร่ามัวและยิ่งห่างไกลจากจำนวนทั้งหมดยิ่งทำให้ภาพเบลอแย่ลง

คือ5.5pxองค์ประกอบที่พร่าเลือนที่สุด5.1pxอย่างน้อยที่สุด

แค่คิดว่าฉันโยนนี่ในกรณีที่มันช่วยใคร


ขอบคุณนี่เป็นปัญหาในกรณีของฉัน - ฉันใช้ translateY (-50%) ซึ่งต้องมีการประเมินค่าเป็นพิกเซลพิกเซล
b4tch

3

ฉันโกงปัญหาโดยใช้การเปลี่ยนทีละขั้นตอนไม่ราบรื่น

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

มันไม่ใช่การแก้มันเป็นการโกงและไม่สามารถใช้ได้ทุกที่

ฉันไม่สามารถอธิบายได้ แต่ใช้งานได้สำหรับฉัน ไม่มีคำตอบอื่นใดที่ช่วยฉันได้ (OSX, Chrome 63, จอแสดงผลที่ไม่ใช่ Retina)

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


ในซอของคุณสั่นเหมือนพาร์กินสัน แต่ในกรณีของฉันทำงาน
Tárcio Zemel

2

ปรับสเกลเป็นสองเท่าและนำลงมาครึ่งหนึ่งพร้อมกับzoomทำงานให้ฉัน

transform: scale(2);
zoom: 0.5;

ดูเหมือนว่าจะใช้งานได้ในโครเมี่ยมสำหรับรูปภาพ น่าเสียดายที่มันยังแก้ไข html ที่คุณใส่ไว้ด้วย
Jack Davidson

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

สำหรับฉันตอนนี้ในปีพ. ศ. 2561 สิ่งเดียวที่แก้ไขปัญหาของฉัน (เส้นสีขาวผิดเพี้ยนที่วิ่งผ่านภาพบนโฮเวอร์) กำลังใช้สิ่งนี้กับองค์ประกอบลิงก์ของฉันซึ่งถือองค์ประกอบภาพที่มี 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;
}

ใช่ 'เบลอ (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

เพิ่งได้รับปัญหาเดียวกัน ลองกำหนดตำแหน่ง: สัมพันธ์กับองค์ประกอบหลักที่ใช้งานได้สำหรับฉัน


5
คุณมีตัวอย่างของการทำงานนี้หรือไม่? ฉันไม่รู้ว่ามันจะช่วยได้อย่างไร
Zach Saucier

2
หากคุณสามารถแก้ไขคำตอบของคุณและอธิบายว่ารหัสที่คุณแสดงนั้นเป็นอย่างไรและสาเหตุ / วิธีการที่รหัสดังกล่าวตอบคำถามนั้นจะช่วยได้จริงๆ การบล็อกรหัสด้วยตนเองมักไม่เป็นคำตอบที่มีประโยชน์
Lea Cohen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.