在Chrome中更改过滤器时,图像会在悬停时移动

时间:2021-11-17 08:17:19

I have an image, when i blur it on hover, it slightly moves, it's like the image shakes in its position, problem only occurs in chrome ( tested with: chromium 63 linux-x86_64 ),

我有一个图像,当我在悬停时模糊它,它稍微移动,就像图像在其位置抖动,问题只发生在铬(测试:铬63 linux-x86_64),

.item img{
  transition: 250ms all ease-in-out;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

.item:hover img{
  filter: blur(2px)
}

I thaught it might be related to this issue, but none of the solutions worked.

我认为它可能与这个问题有关,但没有一个解决方案有效。

在Chrome中更改过滤器时,图像会在悬停时移动

UPDATE :

As @Chase said, this is a chrome bug and the most stable solution is to wait for it to be fixed. but for now, the best solution for this issue is @kosh Very's answer

正如@Chase所说,这是一个chrome bug,最稳定的解决方案就是等待它修复。但就目前而言,这个问题的最佳解决方案是@kosh Very的答案

5 个解决方案

#1


7  

This is a confirmed Chrome bug that popped up in a recent update, and should hopefully get resolved soon.

这是在最近的更新中出现的已确认的Chrome错误,应该很快就会得到解决。

Here's a reduced test case: https://codepen.io/chasebank/pen/KZgYXK

这是一个简化的测试用例:https://codepen.io/chasebank/pen/KZgYXK

Here's the Chromium issue marked for triage.

这是标记为分类的Chromium问题。

I think the best thing to do for now is nothing. Wait for a proper fix to be implemented. It's never a good idea to hack around an acknowledge browser bug.

我认为现在最好的事情就是什么都没有。等待实施正确的修复。破解承认浏览器错误绝不是一个好主意。

We can take some comfort in the fact that the only other people seeing this are Chrome users who recently updated. My first try was asking a Slack channel full of skilled devs, and even they weren't seeing it.

我们可以感到欣慰的是,只有其他人看到这一点的是最近更新过的Chrome用户。我的第一次尝试是要求Slack频道充满熟练的开发者,甚至他们都没有看到它。

$('#toggleBlur').click(function() {
  $('#content').toggleClass('blur')
})
body {
  padding: 5%;
}

div {
  filter: blur(0px);
}

.blur {
  filter: blur(.1px)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="toggleBlur">Toggle blur</button>

<div id="content">
  <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Accusantium eum nisi voluptate eaque! Sequi sit nemo iste. Earum accusantium rerum consectetur cumque sequi maiores maxime reiciendis, alias beatae accusamus labore.</p>
  <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Voluptate enim magnam nemo atque, ad placeat ab unde consequatur minima velit, ipsam tempora laudantium molestias sapiente perspiciatis quaerat modi ratione voluptatem?</p>
  <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Deleniti commodi cum sed nemo fugiat non esse ex quos consectetur ipsam alias laboriosam, cumque eaque omnis quae accusamus, repellat dolore modi!</p>
</div>

#2


3  

I have two solutions for you:

我有两个解决方案:

filter:blur(0.2px) hack (don't ask me how it works)

过滤器:模糊(0.2px)hack(不要问我它是如何工作的)

.item img
{
  transition: filter 250ms ease-in-out;
  filter: blur(0.2px); /* the lowest value I could get on my machine: 0.12805650383234025436px */
  image-rendering: -webkit-optimize-contrast; /* just in case quality degrades */
}

.item:hover img
{
  filter: blur(2px);
}

Jokes aside, this is probably caused by floating number optimizations done by the Processing Unit, so by setting blur to .2px I am not animating blur(0px), but instead start from another value and instead of calculating it like this (assume we have linear easing):

除了笑话,这可能是由处理单元完成的浮点数优化引起的,所以通过将模糊设置为.2px我不是动画模糊(0px),而是从另一个值开始而不是像这样计算它(假设我们有线性宽松):

frame1: 0, frame2: .1, frame3: .2, frame4: .3, ...

frame1:0,frame2:.1,frame3:.2,frame4:.3,...

it calculates it like that:

它计算如下:

frame1: .2, frame2: .2666, frame3: .3332, ...

frame1:.2,frame2:.2666,frame3:.3332,...

So the incremental value has changed and no longer causes that misposition. Of course there's no proper math here (this is especially tricky with easings), but you get the idea.

因此增量值已经改变,不再导致错位。当然这里没有适当的数学(这对于缓和来说尤其棘手),但你明白了。

This also skips the first frame with jiggle as well.

这也会跳过第一帧的摇晃。



Duplicate blurred image and toggle between them (also the most performant way)

复制模糊图像并在它们之间切换(也是最高效的方式)

<div class="item">
    <img class="blurred"  src="https://www.wikihow.com/images/thumb/2/25/Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg/aid8673811-v4-728px-Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg" alt="">
    <img class="original" src="https://www.wikihow.com/images/thumb/2/25/Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg/aid8673811-v4-728px-Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg" alt="">
</div>

.item
{
  position: relative;
}

.item img
{
  max-width: 300px;
  transition: opacity 250ms ease-in-out;
  will-change: opacity;
}

.item .original
{
  transition-delay: 0;
}

.item .blurred
{
  position: absolute;
  filter: blur(5px);
  opacity: 0;
  transition-delay: .1s;
}

.item:hover .original
{
  opacity: 0;
  transition-delay: .2s;
}
.item:hover .blurred
{
  opacity: 1;
  transition-delay: .1s;
}

#3


2  

My two cents:

我的两分钱:

.item {
  width: 200px;
  height: 150px;
  overflow:hidden;
}

img {
  width: 200px;
  transition:filter .5s;
  
  transform: translate3d(-1px, -1px, 0);
  border:solid 1px transparent;
  border-width:1px 0 0 1px;
}

img:hover {
  filter: blur(5px);
}
<div class="item">
  <img src="https://www.wikihow.com/images/thumb/2/25/Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg/aid8673811-v4-728px-Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg" alt="">
</div>

#4


1  

The only way i found to make this work properly is using a svg filter and animate the filter blur with GSAP.

我发现使其正常工作的唯一方法是使用svg过滤器并使用GSAP为过滤器模糊设置动画。

https://jsfiddle.net/eg5yhu26/4/

var timeline = TweenMax.to("#hue1feGaussianBlur", 5, {
  paused: true,
  attr: {
    "stdDeviation": 5
  },
  onUpdateParams: ["{self}"]
});

$(document).on("mouseenter", ".c-grid__item a", function() {
  timeline.play();
});
$(document).on("mouseleave", ".c-grid__item a", function() {
  timeline.reverse();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.14.2/TweenMax.min.js"></script>
<div class="c-grid">
  <div class="c-grid__item">
    <a href="" title="">
      <svg width="100%" height="100%" viewBox="0 0 538 196" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <defs>Using feColorMatrix for Tint FX</defs>
        <!--<filter id="hue1">
        <feColorMatrix id="hue1feColorMatrix" in="SourceGraphic" type="hueRotate" values="0"/>
 </filter>-->
        <filter id="hue1" x="0" y="0">
          <feGaussianBlur id="hue1feGaussianBlur" in="SourceGraphic" stdDeviation="0" />
        </filter>
        <image xlink:href="https://www.wikihow.com/images/thumb/2/25/Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg/aid8673811-v4-728px-Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg" width="100%" height="100%" filter="url(#hue1)" />
      </svg>
    </a>
  </div>
</div>

#5


0  

I did a lot of research and I tried a lot of different ways but nothing seems to fix this glitch. The only way to avoid having this jump is to have the blur effect at the start on the image or remove the transition (as there is no issue without transition and of course this not an option to consider).

我做了很多研究,我尝试了很多不同的方法,但似乎没有什么能解决这个问题。避免跳转的唯一方法是在图像的开头有模糊效果或删除过渡(因为没有过渡没有问题,当然这不是一个考虑的选项)。

So the workaround I have found is to use two different images and have the blur(1px) at the start.

所以我找到的解决方法是使用两个不同的图像并在开始时具有模糊(1px)。

The idea is to have the image with the blur effect hidden by opacity:0 and use the same image as a background to simulate an initial image without blur effect. Then the trick is to make the transition of opacity faster than the transition of the filter so we can see the effect of blur(1px) and then the effect of blur(2px)

我们的想法是使图像的模糊效果被不透明度隐藏:0并使用相同的图像作为背景来模拟没有模糊效果的初始图像。然后诀窍是使不透明度的过渡比过滤器的过渡更快,这样我们就可以看到模糊效果(1px)然后模糊效果(2px)

.item {
  width: 200px;
  height: 150px;
  background: url(https://www.wikihow.com/images/thumb/2/25/Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg/aid8673811-v4-728px-Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg);
  background-size: 100%;
}

img {
  width: 200px;
  display: inline-block;
  transition: 2s filter ease-in-out, 0.1s opacity ease-in-out;
  filter: blur(1px);
  opacity: 0;
}

img:hover {
  opacity: 1;
  filter: blur(2px);
}
<div class="item">
  <img src="https://www.wikihow.com/images/thumb/2/25/Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg/aid8673811-v4-728px-Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg" alt="">
</div>

I assume this trick involve more HTML/CSS and you have to change each image on the site, but you can for example create a jQuery code that will do this for. You simply create a class that you append to any image where you need this effect then you target this class and add the necessary code for the trick.

我假设这个技巧涉及更多的HTML / CSS,你必须更改网站上的每个图像,但你可以创建一个jQuery代码来执行此操作。您只需创建一个类,将其附加到需要此效果的任何图像,然后定位此类并为该技巧添加必要的代码。

Here is an example:

这是一个例子:

$('img.blur').each(function() {
  var url = $(this).attr('src');
  $(this).wrap("<div style='display:inline-block;font-size:0;background-image:url(" + url + ");background-size: 100%;'></div>")
})
.blur {
  transition: 2s filter ease-in-out, 0.1s opacity ease-in-out;
  filter: blur(1px);
  opacity: 0;
}

.blur:hover {
  opacity: 1;
  filter: blur(3px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<img src="https://www.wikihow.com/images/thumb/2/25/Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg/aid8673811-v4-728px-Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg" width="200" class="blur">

<img src="https://lorempixel.com/300/300/" width="300" class="blur" />

<img src="https://lorempixel.com/400/400/" width="400" class="blur" />

#1


7  

This is a confirmed Chrome bug that popped up in a recent update, and should hopefully get resolved soon.

这是在最近的更新中出现的已确认的Chrome错误,应该很快就会得到解决。

Here's a reduced test case: https://codepen.io/chasebank/pen/KZgYXK

这是一个简化的测试用例:https://codepen.io/chasebank/pen/KZgYXK

Here's the Chromium issue marked for triage.

这是标记为分类的Chromium问题。

I think the best thing to do for now is nothing. Wait for a proper fix to be implemented. It's never a good idea to hack around an acknowledge browser bug.

我认为现在最好的事情就是什么都没有。等待实施正确的修复。破解承认浏览器错误绝不是一个好主意。

We can take some comfort in the fact that the only other people seeing this are Chrome users who recently updated. My first try was asking a Slack channel full of skilled devs, and even they weren't seeing it.

我们可以感到欣慰的是,只有其他人看到这一点的是最近更新过的Chrome用户。我的第一次尝试是要求Slack频道充满熟练的开发者,甚至他们都没有看到它。

$('#toggleBlur').click(function() {
  $('#content').toggleClass('blur')
})
body {
  padding: 5%;
}

div {
  filter: blur(0px);
}

.blur {
  filter: blur(.1px)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="toggleBlur">Toggle blur</button>

<div id="content">
  <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Accusantium eum nisi voluptate eaque! Sequi sit nemo iste. Earum accusantium rerum consectetur cumque sequi maiores maxime reiciendis, alias beatae accusamus labore.</p>
  <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Voluptate enim magnam nemo atque, ad placeat ab unde consequatur minima velit, ipsam tempora laudantium molestias sapiente perspiciatis quaerat modi ratione voluptatem?</p>
  <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Deleniti commodi cum sed nemo fugiat non esse ex quos consectetur ipsam alias laboriosam, cumque eaque omnis quae accusamus, repellat dolore modi!</p>
</div>

#2


3  

I have two solutions for you:

我有两个解决方案:

filter:blur(0.2px) hack (don't ask me how it works)

过滤器:模糊(0.2px)hack(不要问我它是如何工作的)

.item img
{
  transition: filter 250ms ease-in-out;
  filter: blur(0.2px); /* the lowest value I could get on my machine: 0.12805650383234025436px */
  image-rendering: -webkit-optimize-contrast; /* just in case quality degrades */
}

.item:hover img
{
  filter: blur(2px);
}

Jokes aside, this is probably caused by floating number optimizations done by the Processing Unit, so by setting blur to .2px I am not animating blur(0px), but instead start from another value and instead of calculating it like this (assume we have linear easing):

除了笑话,这可能是由处理单元完成的浮点数优化引起的,所以通过将模糊设置为.2px我不是动画模糊(0px),而是从另一个值开始而不是像这样计算它(假设我们有线性宽松):

frame1: 0, frame2: .1, frame3: .2, frame4: .3, ...

frame1:0,frame2:.1,frame3:.2,frame4:.3,...

it calculates it like that:

它计算如下:

frame1: .2, frame2: .2666, frame3: .3332, ...

frame1:.2,frame2:.2666,frame3:.3332,...

So the incremental value has changed and no longer causes that misposition. Of course there's no proper math here (this is especially tricky with easings), but you get the idea.

因此增量值已经改变,不再导致错位。当然这里没有适当的数学(这对于缓和来说尤其棘手),但你明白了。

This also skips the first frame with jiggle as well.

这也会跳过第一帧的摇晃。



Duplicate blurred image and toggle between them (also the most performant way)

复制模糊图像并在它们之间切换(也是最高效的方式)

<div class="item">
    <img class="blurred"  src="https://www.wikihow.com/images/thumb/2/25/Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg/aid8673811-v4-728px-Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg" alt="">
    <img class="original" src="https://www.wikihow.com/images/thumb/2/25/Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg/aid8673811-v4-728px-Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg" alt="">
</div>

.item
{
  position: relative;
}

.item img
{
  max-width: 300px;
  transition: opacity 250ms ease-in-out;
  will-change: opacity;
}

.item .original
{
  transition-delay: 0;
}

.item .blurred
{
  position: absolute;
  filter: blur(5px);
  opacity: 0;
  transition-delay: .1s;
}

.item:hover .original
{
  opacity: 0;
  transition-delay: .2s;
}
.item:hover .blurred
{
  opacity: 1;
  transition-delay: .1s;
}

#3


2  

My two cents:

我的两分钱:

.item {
  width: 200px;
  height: 150px;
  overflow:hidden;
}

img {
  width: 200px;
  transition:filter .5s;
  
  transform: translate3d(-1px, -1px, 0);
  border:solid 1px transparent;
  border-width:1px 0 0 1px;
}

img:hover {
  filter: blur(5px);
}
<div class="item">
  <img src="https://www.wikihow.com/images/thumb/2/25/Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg/aid8673811-v4-728px-Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg" alt="">
</div>

#4


1  

The only way i found to make this work properly is using a svg filter and animate the filter blur with GSAP.

我发现使其正常工作的唯一方法是使用svg过滤器并使用GSAP为过滤器模糊设置动画。

https://jsfiddle.net/eg5yhu26/4/

var timeline = TweenMax.to("#hue1feGaussianBlur", 5, {
  paused: true,
  attr: {
    "stdDeviation": 5
  },
  onUpdateParams: ["{self}"]
});

$(document).on("mouseenter", ".c-grid__item a", function() {
  timeline.play();
});
$(document).on("mouseleave", ".c-grid__item a", function() {
  timeline.reverse();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.14.2/TweenMax.min.js"></script>
<div class="c-grid">
  <div class="c-grid__item">
    <a href="" title="">
      <svg width="100%" height="100%" viewBox="0 0 538 196" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <defs>Using feColorMatrix for Tint FX</defs>
        <!--<filter id="hue1">
        <feColorMatrix id="hue1feColorMatrix" in="SourceGraphic" type="hueRotate" values="0"/>
 </filter>-->
        <filter id="hue1" x="0" y="0">
          <feGaussianBlur id="hue1feGaussianBlur" in="SourceGraphic" stdDeviation="0" />
        </filter>
        <image xlink:href="https://www.wikihow.com/images/thumb/2/25/Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg/aid8673811-v4-728px-Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg" width="100%" height="100%" filter="url(#hue1)" />
      </svg>
    </a>
  </div>
</div>

#5


0  

I did a lot of research and I tried a lot of different ways but nothing seems to fix this glitch. The only way to avoid having this jump is to have the blur effect at the start on the image or remove the transition (as there is no issue without transition and of course this not an option to consider).

我做了很多研究,我尝试了很多不同的方法,但似乎没有什么能解决这个问题。避免跳转的唯一方法是在图像的开头有模糊效果或删除过渡(因为没有过渡没有问题,当然这不是一个考虑的选项)。

So the workaround I have found is to use two different images and have the blur(1px) at the start.

所以我找到的解决方法是使用两个不同的图像并在开始时具有模糊(1px)。

The idea is to have the image with the blur effect hidden by opacity:0 and use the same image as a background to simulate an initial image without blur effect. Then the trick is to make the transition of opacity faster than the transition of the filter so we can see the effect of blur(1px) and then the effect of blur(2px)

我们的想法是使图像的模糊效果被不透明度隐藏:0并使用相同的图像作为背景来模拟没有模糊效果的初始图像。然后诀窍是使不透明度的过渡比过滤器的过渡更快,这样我们就可以看到模糊效果(1px)然后模糊效果(2px)

.item {
  width: 200px;
  height: 150px;
  background: url(https://www.wikihow.com/images/thumb/2/25/Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg/aid8673811-v4-728px-Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg);
  background-size: 100%;
}

img {
  width: 200px;
  display: inline-block;
  transition: 2s filter ease-in-out, 0.1s opacity ease-in-out;
  filter: blur(1px);
  opacity: 0;
}

img:hover {
  opacity: 1;
  filter: blur(2px);
}
<div class="item">
  <img src="https://www.wikihow.com/images/thumb/2/25/Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg/aid8673811-v4-728px-Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg" alt="">
</div>

I assume this trick involve more HTML/CSS and you have to change each image on the site, but you can for example create a jQuery code that will do this for. You simply create a class that you append to any image where you need this effect then you target this class and add the necessary code for the trick.

我假设这个技巧涉及更多的HTML / CSS,你必须更改网站上的每个图像,但你可以创建一个jQuery代码来执行此操作。您只需创建一个类,将其附加到需要此效果的任何图像,然后定位此类并为该技巧添加必要的代码。

Here is an example:

这是一个例子:

$('img.blur').each(function() {
  var url = $(this).attr('src');
  $(this).wrap("<div style='display:inline-block;font-size:0;background-image:url(" + url + ");background-size: 100%;'></div>")
})
.blur {
  transition: 2s filter ease-in-out, 0.1s opacity ease-in-out;
  filter: blur(1px);
  opacity: 0;
}

.blur:hover {
  opacity: 1;
  filter: blur(3px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<img src="https://www.wikihow.com/images/thumb/2/25/Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg/aid8673811-v4-728px-Collect-Bodily-Fluid-Samples-from-a-Cat-Step-16.jpg" width="200" class="blur">

<img src="https://lorempixel.com/300/300/" width="300" class="blur" />

<img src="https://lorempixel.com/400/400/" width="400" class="blur" />