CSS 过渡效果使图像模糊/移动图像 1px,在 Chrome 中?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15464055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 22:04:11  来源:igfitidea点击:

CSS transition effect makes image blurry / moves image 1px, in Chrome?

cssimagehoverpositioningtranslate-animation

提问by Lewis

I have some CSS that on hover, a CSS transition effect will moves a div.

我有一些 CSS 在悬停时,CSS 过渡效果会移动一个 div。

The problem, as you can see in the example, is that the translatetransition has the horrible side effect of making the image in the div move by 1px down/right (and possibly resize ever so slightly?) so that it appears out of place and out of focus...

正如您在示例中所看到的,问题在于translate过渡具有可怕的副作用,使 div 中的图像向下/向右移动 1px(并且可能稍微调整大小?),因此它看起来不合适并且失焦...

The glitch seems to apply the whole time the hover effect is applied, and from a process of trial and error I can safely say only seems to occur when the translate transition moves the div (box shadow and opacity are also applied but make no difference to the error when removed).

小故障似乎在应用悬停效果的整个过程中都适用,并且从反复试验的过程中,我可以有把握地说似乎只有在平移过渡移动 div 时才会发生(也应用了框阴影和不透明度,但对删除时的错误)。

The problem only seems to happen when the page has scrollbars. So the example with just one instance of the div is fine, but once more identical divs are added and the page therefore requires a scrollbar the problem strikes again...

该问题似乎仅在页面具有滚动条时发生。因此,只有一个 div 实例的示例很好,但是一旦添加了更多相同的 div,页面因此需要滚动条,问题再次出现......

回答by sampoh

2020 update

2020年更新

  • If you have issues with blurry images, be sure to check answers from below as well, especially the image-renderingCSS property.
  • For best practice accessibility and SEO wise you could replace the background image with an <img>tag using object-fitCSS property.
  • 如果您有模糊图像的问题,请务必检查下面的答案,尤其是image-renderingCSS 属性。
  • 为了最佳实践可访问性和 SEO 明智,您可以<img>使用object-fitCSS 属性用标签替换背景图像。


Original answer

原答案

Try this in your CSS:

在你的CSS 中试试这个:

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

What this does is it makes the division to behave "more 2D".

这样做的目的是使部门表现得“更加二维”。

  • Backface is drawn as a default to allow flipping things with rotate and such. There's no need to that if you only move left, right, up, down, scale or rotate (counter-)clockwise.
  • Translate Z-axis to always have a zero value.
  • Chrome now handles backface-visibilityand transformwithout the -webkit-prefix. I currently don't know how this affects other browsers rendering (FF, IE), so use the non-prefixed versions with caution.
  • 默认情况下绘制背面以允许使用旋转等翻转事物。如果您只向左、向右、向上、向下、缩放或旋转(逆)时针,则无需这样做。
  • 将 Z 轴平移到始终为零值。
  • Chrome 现在可以处理backface-visibility并且transform没有-webkit-前缀。我目前不知道这如何影响其他浏览器渲染(FF、IE),因此请谨慎使用非前缀版本。

回答by sol0mka

You need to apply 3d transform to the element, so it will get its own composite layer. For instance:

您需要对元素应用 3d 变换,因此它将获得自己的复合层。例如:

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

or

或者

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

More about layer creation criteria you can read right here: Accelerated Rendering in Chrome

有关图层创建标准的更多信息,您可以在此处阅读:Chrome 中的加速渲染



An explanation:

一个解释:

Examples (hover green box):

示例(悬停绿色框):

When you use any transition on your element it cause browser to recalculate styles, then re-layout your content even if transition property is visual (in my examples it is an opacity) and finaly paint an element:

当您在元素上使用任何过渡时,它会导致浏览器重新计算样式,然后重新布局您的内容,即使过渡属性是可视的(在我的示例中它是一个不透明度)并最终绘制一个元素:

screenshot

截屏

The issue here is re-layout of the content that can make an effect of "dancing" or "blinking" elements on the page while transition happens. If you will go to settings, check "Show composite layers" checkbox and then apply 3d transform to an element, you will see that it gets it's own layer which outlined with orange border.

这里的问题是内容的重新布局,可以在转换发生时在页面上产生“跳舞”或“闪烁”元素的效果。如果您将进入设置,选中“显示复合图层”复选框,然后将 3d 变换应用于元素,您将看到它获得自己的图层,该图层带有橙色边框。

screenshot

截屏

After element gets its own layer, browser just needs to composite layers on transition without re-layout or even paint operations so problem have to be solved:

元素获得自己的图层后,浏览器只需要在过渡时合成图层,无需重新布局甚至绘制操作,因此必须解决问题:

screenshot

截屏

回答by xb1itz

Had the same problem with embeded youtube iframe (Translations were used for centering iframe element). None of the solutions above worked until tried reset css filtersand magic happened.

嵌入的 youtube iframe 有同样的问题(翻译用于居中 iframe 元素)。在尝试重置 css 过滤器和魔法发生之前,上述解决方案都不起作用

Structure:

结构:

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

Style [before]

样式 [之前]

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

Style [after]

样式 [之后]

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

回答by Felipez

I recommended an experimental new attribute CSS I tested on latest browser and it's good:

我推荐了一个我在最新浏览器上测试过的实验性新属性 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+                */

With this the browser will know the algorithm for rendering

有了这个,浏览器将知道渲染算法

回答by ashrobbins

Just found another reason why an element goes blurry when being transformed. I was using transform: translate3d(-5.5px, -18px, 0);to re-position an element once it had been loaded in, however that element became blurry.

刚刚找到了一个元素在转换时变得模糊的另一个原因。我曾经transform: translate3d(-5.5px, -18px, 0);在一个元素加载后重新定位它,但是该元素变得模糊。

I tried all the suggestions above but it turned out that it was due to me using a decimal value for one of the translate values. Whole numbers don't cause the blur, and the further away I went from the whole number the worse the blur became.

我尝试了上面的所有建议,但结果证明这是由于我对其中一个翻译值使用了十进制值。整数不会导致模糊,我离整数越远,模糊就越严重。

i.e. 5.5pxblurs the element the most, 5.1pxthe least.

5.5px最模糊元素,5.1px最少。

Just thought I'd chuck this here in case it helps anybody.

只是想我会把它扔在这里以防万一它对任何人都有帮助。

回答by Evgeny Gendel

I cheated problem using transition by steps, not smoothly

我使用分步过渡作弊问题,不顺利

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

It is not a solving, it is a cheating and can not be applied everywhere.

这不是解决,而是作弊,不能到处应用。

I can't explain it, but it works for me. None of another answers helps me (OSX, Chrome 63, Non-Retina display).

我无法解释,但它对我有用。没有其他答案对我有帮助(OSX、Chrome 63、非 Retina 显示器)。

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

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

回答by Kushagra Gour

Scaling to double and bringing down to half with zoomworked for me.

缩放到两倍并减少到一半zoom对我有用。

transform: scale(2);
zoom: 0.5;

回答by Adam Orlov

I've tried around 10 possibly solutions. Mixed them up and they still didn't work correctly. There was always 1px shake at the end.

我已经尝试了大约 10 种可能的解决方案。将它们混合在一起,它们仍然无法正常工作。最后总是有 1px 的抖动。

I find solution by reducing transition time on filter.

我通过减少过滤器的转换时间来找到解决方案。

This didn't work:

这不起作用:

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

Solution:

解决方案:

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

Try this in 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>

I hope this helps someone.

我希望这可以帮助别人。

回答by mateostabio

For me, now in 2018. The only thing that fixed my problem (a white glitchy-flicker line running through an image on hover) was applying this to my link element holding the image element that has transform: scale(1.05)

对我来说,现在是 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;
}

回答by Fred K

Try filter: blur(0);

尝试 filter: blur(0);

It worked for me

它对我有用