CSS转换效果会使图像模糊/移动图像1px,在Chrome中?

时间:2013-03-17 17:47:29

标签: css image hover positioning translate-animation

当div跳过时,CSS过渡效果会移动div。

正如您在示例中看到的那样,问题是“转换”转换具有可怕的副作用,即使div中的图像向下/向右移动1px(并且可能稍微调整一次?)它看起来不合适而且没有焦点...

故障似乎适用于应用悬停效果的整个时间,并且从试验和错误的过程我可以肯定地说,当翻译过渡移动div时似乎只会发生(框阴影和不透明度也被应用但是删除后没有差异)。

第二次编辑:实际上,问题没有解决!

在创建一个JSFiddle来说明问题时,我偶然发现了一个有趣的观察结果。只有页面有滚动条时才会出现此问题。所以只有一个div实例的例子很好,但是一旦添加了相同的div,因此页面需要滚动条,问题再次出现......

任何想法?!

14 个答案:

答案 0 :(得分:238)

您是否在 CSS

中尝试了此操作
.yourDivClass {
    /* ... */

    -webkit-backface-visibility: hidden;
    -webkit-transform: translateZ(0) scale(1.0, 1.0);
}

这样做会使分裂表现得更“2D”。

  • 背面被绘制为默认设置,允许使用旋转翻转内容 等等。如果您只是向左,向右,向上,向下,缩放或顺时针旋转(反向),则无需这样做。
  • 将Z轴平移为始终为零值。

修改

Chrome现在处理backface-visibilitytransform而没有-webkit-前缀。我目前不知道这会如何影响其他浏览器渲染(FF,IE),所以请谨慎使用非前缀版本。

答案 1 :(得分:85)

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

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

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

有关图层创建条件的更多信息,请参阅此处:Accelerated Rendering in Chrome


解释:

示例(悬停绿框):

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

screenshot

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

screenshot

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

screenshot

答案 2 :(得分:38)

嵌入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);
}

答案 3 :(得分:30)

我推荐了一个实验性的新属性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+                */

有了这个,浏览器就会知道用于渲染的算法

答案 4 :(得分:4)

刚刚发现元素在转换时变得模糊的另一个原因。我正在使用transform: translate3d(-5.5px, -18px, 0);在元素加载后重新定位元素,但该元素变得模糊。

我尝试了上面的所有建议,但事实证明这是因为我使用了十进制值作为其中一个翻译值。整数不会导致模糊,而且距离整数越远,模糊变得越差。

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

以为我会把它放在这里以防万一它可以帮助任何人。

答案 5 :(得分:3)

我通过步骤过渡而不是顺利地欺骗了问题

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

这不是一个解决方案,它是一种作弊,无法在任何地方应用。

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

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

答案 6 :(得分:2)

使用zoom缩放为一倍并降低到一半为我工作。

transform: scale(2);
zoom: 0.5;

答案 7 :(得分:1)

尝试filter: blur(0);

它对我有用

答案 8 :(得分:1)

我尝试了大约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>

我希望这有助于某人。

答案 9 :(得分:1)

对我来说,现在是2018年。唯一解决了我的问题(在悬停时穿过图像的白色毛刺闪烁线)将其应用于我的链接元素,其中包含transform: scale(1.05) <的图像元素/ p>

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;
}

答案 10 :(得分:1)

这些都没有用,对我有用的是缩小图像。

因此,根据您想要图像的大小或图像的分辨率,您可以执行以下操作:

.ok {
      transform: perspective(100px) rotateY(0deg) scale(0.5);
      transition: transform 1s;
      object-fit:contain;
}
.ok:hover{
      transform: perspective(100px) rotateY(-10deg) scale(0.5);
}

/* Demo Preview Stuff */
.bad {
   max-width: 320px;
   object-fit:contain;
   transform: perspective(100px) rotateY(0deg);
   transition: transform 1s;
}
.bad:hover{
      transform: perspective(100px) rotateY(-10deg);
}

div {
     text-align: center;
     position: relative;
     display: flex;
}
h3{
    position: absolute;
    bottom: 30px;
    left: 0;
    right: 0;
}
     
.b {
    display: flex;
}
<center>
<h2>Hover on images</h2>
<div class="b">
<div>
  <img class="ok" src='https://www.howtogeek.com/wp-content/uploads/2018/10/preview-11.png'>
  <h3>Sharp</h3>
</div>

<div>
  <img class="bad" src='https://www.howtogeek.com/wp-content/uploads/2018/10/preview-11.png'>
  <h3>Blurry</h3>
</div>

</div>

</center>

图片应该缩小,确保你有一个大的图像分辨率

答案 11 :(得分:1)

我遇到了类似的模糊文本问题,但只有后续的 div 受到影响。出于某种原因,在我进行转换的那个之后的下一个 div 是模糊的。

我尝试了此线程中推荐的所有内容,但没有任何效果。 对我来说重新排列我的 div 有效。我将模糊以下 div 的 div 移到了父 div 的末尾。

如果有人知道为什么,请告诉我。

#before
<header class="container">
      <div class="transformed div">
          <span class="transform wrapper">
            <span class="transformed"></span>
            <span class="transformed"></span>
          </span>
       </div>
       <div class="affected div">
       </div>
     </header>

#after
<header class="container">
   <div class="affected div">
   </div>
  <div class="transformed div">
      <span class="transform wrapper">
        <span class="transformed"></span>
        <span class="transformed"></span>
      </span>
   </div>

 </header>

答案 12 :(得分:0)

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

通过设置转换持续时间.3s的值等于转换时间步骤.3s

,我得到了帮助

答案 13 :(得分:-6)

刚刚遇到同样的问题。尝试设置位置:相对于父元素,这对我有用。