Эффект перехода CSS делает изображение размытым/перемещает изображение 1px, в Chrome?

Когда div разворачивается, эффект перехода CSS перемещает div.

Проблема, как вы можете видеть в этом примере, состоит в том, что переход "переводить" имеет ужасный побочный эффект, заключающийся в том, что изображение в div перемещается на 1px вниз/вправо (и, возможно, немного уменьшится?), так что он выглядит неуместным и не в фокусе...

Сбой, похоже, применяется все время, когда применяется эффект наведения, и из процесса проб и ошибок я могу с уверенностью сказать, что только кажется, что происходит, когда переходный переход перемещает div (также применяются тень окна и непрозрачность, но делают без разницы с ошибкой при удалении).

2nd EDIT: На самом деле проблема НЕ решена!

Создав JSFiddle, чтобы проиллюстрировать проблему, я наткнулся на интересное наблюдение. Проблема возникает только тогда, когда на странице есть полосы прокрутки. Таким образом, пример с одним экземпляром div прекрасен, но еще раз идентичные divs добавлены, и поэтому для страницы требуется панель прокрутки, проблема снова ударяется...

Любые идеи?!

Ответ 1

Вы пробовали это в CSS?

.yourDivClass {
    /* ... */

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

Что это значит, это приводит к тому, что деление ведет себя "больше 2D".

  • Обратная сторона рисуется как значение по умолчанию, позволяющее переворачивать вещи с помощью поворота и тому подобное. Нет необходимости в этом, если вы только перемещаете влево, вправо, вверх, вниз, масштабируете или вращаете (против часовой стрелки).
  • Переведите ось Z, чтобы всегда иметь нулевое значение.

Edit

Теперь Chrome обрабатывает backface-visibility и transform без префикса -webkit-. В настоящее время я не знаю, как это влияет на рендеринг других браузеров (FF, IE), поэтому используйте предопределенные версии с осторожностью.

Ответ 2

Вам нужно применить 3d-преобразование к элементу, чтобы он получил свой собственный составной слой. Например:

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

или

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

Подробнее о критериях создания слоев, которые вы можете прочитать здесь: Ускоренный рендеринг в Chrome


Объяснение:

Примеры (наведите зеленый квадрат):

Когда вы используете какой-либо переход на свой элемент, он заставляет браузер пересчитывать стили, а затем повторно размещать ваш контент, даже если свойство перехода является визуальным (в моих примерах это непрозрачность) и окончательно нарисовать элемент:

screenshot

Проблема заключается в повторной компоновке содержимого, которое может влиять на "танцы" или "мигание" элементов на странице при переходе. Если вы перейдете к настройкам, установите флажок "Показывать составные слои", а затем примените 3D-преобразование к элементу, вы увидите, что он получает собственный слой, который обозначен оранжевой рамкой.

screenshot

После того, как элемент получает свой собственный слой, браузер просто нуждается в составных слоях при переходе без повторной компоновки или даже рисования, поэтому проблема должна быть решена:

screenshot

Ответ 3

Была та же проблема с встроенным youtube iframe (для центрирования iframe-элемента были использованы переводы). Ни одно из вышеперечисленных решений не работало до тех пор, пока не пробовали reset фильтры 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);
}

Ответ 4

Я рекомендовал экспериментальный новый атрибут 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+                */

При этом браузер будет знать алгоритм рендеринга

Ответ 5

Просто появилась другая причина, по которой элемент становится размытым при преобразовании. Я использовал transform: translate3d(-5.5px, -18px, 0); для повторного позиционирования элемента после его загрузки, однако этот элемент стал размытым.

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

то есть. 5.5px размывает элемент больше всего, 5.1px меньше.

Просто подумал, что я задержу это здесь, если это поможет кому-нибудь.

Ответ 6

Я обманул проблему, используя переход по шагам, а не плавно

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

Это не решение, это обман и не может быть применен везде.

Я не могу это объяснить, но это работает для меня. Ни один из других ответов не помогает мне (OSX, Chrome 63, дисплей без Retina).

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

Ответ 7

Масштабирование в два раза и уменьшение до половины с помощью zoom работало для меня.

transform: scale(2);
zoom: 0.5;

Ответ 8

Попробуйте filter: blur(0);

Это сработало для меня

Ответ 9

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

Мне помогло, установив значение длительности перехода .3s равными шагами синхронизации перехода. .3s

Ответ 10

Я пробовал около 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>

Ответ 11

Для меня сейчас 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;
}

Ответ 12

Просто такая же проблема. Попробуйте установить позицию: относительно родительского элемента, который работал у меня.