Изображение перемещается при наведении курсора при смене фильтра в Chrome

У меня есть изображение, когда я размываю его при наведении, оно слегка перемещается, как будто изображение трясется в своем положении, проблема возникает только в хроме (проверено с помощью: chromium 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)
}

Я думаю, это может быть связано с этой проблемой, но ни один из решения работали.

изображение перемещается при наведении курсора

ОБНОВЛЕНИЕ:

Как сказал @Chase, это ошибка хрома, и самое стабильное решение - дождаться ее исправления. но пока лучшим решением этой проблемы является ответ @kosh Very


person Amin    schedule 20.12.2017    source источник
comment
Вы пробовали добавить transform: translateZ(0); в свой .item img {}? jsfiddle.net/oto7quwL   -  person Andy Hoffman    schedule 21.12.2017
comment
@AndyHoffman, да, даже в твоей скрипке изображение движется!   -  person Amin    schedule 21.12.2017
comment
Это кажется, наконец, исправлено в v73.   -  person Alexander Nied    schedule 28.03.2019


Ответы (5)


Это подтвержденная ошибка Chrome, которая появилась в недавнем обновлении и, надеюсь, скоро будет исправлена.

Вот сокращенный тестовый пример: https://codepen.io/chasebank/pen/KZgYXK

Вот Проблема Chromium отмечена для сортировки.

Я думаю, что сейчас лучше всего ничего не делать. Подождите, пока не будет реализовано правильное исправление. Никогда не стоит исправлять обнаруженную ошибку браузера.

Нас может утешить тот факт, что это видят только пользователи 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>

person Chase    schedule 24.12.2017
comment
У меня все еще есть эта ошибка, с фильтром: преобразование яркости: translate3d (0,0,0), похоже, исправляет ее, хотя у меня нет идеального по пикселям глаза. Должен ли я где-нибудь сообщить об этом? - person eduardogbg; 23.09.2020

У меня есть два решения для вас:

filter: blur (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);
}

Шутки в сторону, это, вероятно, вызвано оптимизацией плавающих чисел, выполненной блоком обработки, поэтому, устанавливая размытие на .2px, я не анимирую размытие (0px), а вместо этого начинаю с другого значения и вместо этого вычисляю его (предположим, что у нас есть линейное ослабление):

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

он рассчитывает это так:

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

Таким образом, инкрементное значение изменилось и больше не вызывает такого неправильного положения. Конечно, здесь нет правильной математики (это особенно сложно с ослаблением), но идею вы поняли.

Это также пропускает первый кадр с покачиванием.



Дублировать размытые изображения и переключаться между ними (также наиболее эффективный способ)

<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;
}
person CyberAP    schedule 24.12.2017
comment
Мне пришлось подтолкнуть его, чтобы размыть (.3px), но это было единственное, что у меня сработало. - person luckyape; 16.01.2018
comment
фильтр: размытие (2 пикселя); у меня работает, заняло час ... - person John Macpherson; 28.02.2021

Мои два цента:

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

person Kosh    schedule 08.02.2018
comment
Работает отлично, спасибо, я сократил код еще больше, и он все еще работает. См. Это перо: codepen.io/DEfusion/pen/VQPGvx - person DEfusion; 09.02.2018
comment
@DEfusion, Спасибо за комментарий! Вы правы, overflow и transform делают свое дело, но border необходимо, чтобы компенсировать сдвиг transform, чтобы добиться идеального пикселя. Хотя в некоторых случаях его можно опустить. - person Kosh; 09.02.2018

Единственный способ, который я нашел, чтобы сделать эту работу правильно, - это использовать фильтр 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>

person Robin Mimeault    schedule 14.01.2018

Я провел много исследований и пробовал много разных способов, но, похоже, ничего не исправляет этот сбой. Единственный способ избежать этого перехода - использовать эффект размытия в начале изображения или удалить переход (поскольку без перехода нет проблем, и, конечно, это не вариант для рассмотрения).

Таким образом, я нашел обходной путь - использовать два разных изображения и иметь blur(1px) в начале.

Идея состоит в том, чтобы изображение с эффектом размытия было скрыто за opacity:0 и использовалось это же изображение в качестве фона для имитации исходного изображения без эффекта размытия. Тогда уловка состоит в том, чтобы сделать переход непрозрачности быстрее, чем переход фильтра, чтобы мы могли видеть эффект blur(1px), а затем эффект blur(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>

Я предполагаю, что этот трюк включает в себя больше HTML / CSS, и вам нужно изменить каждое изображение на сайте, но вы можете, например, создать код jQuery, который будет делать это для. Вы просто создаете класс, который добавляете к любому изображению, где вам нужен этот эффект, затем настраиваете этот класс и добавляете необходимый код для трюка.

Вот пример:

$('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" />

person Temani Afif    schedule 24.12.2017