Преобразование CSS3 вызывает мерцание текста в Safari и Firefox Mac Yosemite

у меня есть эта странная проблема в Safari и Firefox (Mac/Yosemite), которая заставляет почти весь текст на странице мерцать при наведении курсора на преобразующий элемент.

пример gif: (Firefox, Yosemite)

enter image description here

.usp {
   //USP has an icon that is defined below
    opacity: .4;
    @include transition(all .3s ease-in-out);


    &:hover { 
        opacity: 1;
        @include transition(all .3s ease-in-out);


        .icon {
            @include transform(scale(1.1));
            @include transition(all 1.7s ease-in-out);
        }
    } // :hover
} 

.usp .icon {
    display: block;
    height: 75px;
    width: 75px;
    // Insert background-image sprite (removed from this example)
    @include transition(all .3s ease-in-out); 
    @include transform(scale(1.0));
}

Я пробовал следующие вещи:

добавьте все возможные комбинации этих стилей в тело, преобразующий элемент и / или его родитель

-webkit-transform-style:preserve-3d;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
 backface-visibility: hidden;
-webkit-filter: opacity(.9999);
-webkit-font-smoothing: antialiased;
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
 transform: translate3d(0, 0, 0);
-webkit-font-smoothing: subpixel-antialiased;
-webkit-text-stroke: 0.35px;

Если (стили ниже) применяются к тело, проблема исправлена в Safari, но не в Firefox, поскольку это не браузер webkit.

-webkit-transform: translate3d(0, 0, 0);
-webkit-text-stroke: 0.35px;

Я буквально не знаю, что вызывает это и как я могу это исправить!

7 ответов


хорошо!

после недели тестирования, удаления и добавления правил CSS я, наконец, нашел решение, которое исправило мою проблему. Первоначально у меня была эта проблема как в Firefox 39, так и в Safari 9, но Firefox таинственно исправился с последним обновлением. Однако Safari этого не сделала. Проблема связана с 3D-рендерингом элементов на странице. Элемент, который я пытался масштабировать, должен был быть преобразован в 3D-контекст, мерцающие элементы на странице переключались между 2D и 3D как объяснено @Woodrow-Barlow в других ответах.

добавлять

-webkit-transform: translate3d(0, 0, 0);

для мерцающих элементов и, таким образом, рендеринга их в 3D при загрузке страницы, им больше не нужно было переключаться!

правка 1: для людей, у которых есть эта проблема в других браузерах, взгляните на свойство CSS " will-change: https://dev.opera.com/articles/css-will-change-property/


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

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

ваш эффект наведения использует преобразование, которое ваш браузер счел подходящим для аппаратного ускорения рендеринга GPU (скорее всего, вызванного scale(1.1) transformation), и поэтому он временно переместил рендеринг на GPU во время анимации/перехода наведения. После того, как анимация будет сделано, Процессор снова рендеринга. Из-за различных стратегий рендеринга, используемых различными аппаратными средствами, текст выглядит по-разному (менее четким), пока GPU отвечает.

к сожалению, у нас нет (пока) явного контроля аппаратного ускорения через CSS-браузер устанавливает это всякий раз, когда он хочет. Однако мы можем установить некоторые свойства, которые мы подозреваемый переведет браузер в режим GPU с аппаратным ускорением. Теория здесь заключается в том, что мы будем держать браузер в режиме GPU, даже когда анимация не происходит, так что мы не видим "мерцание".

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

похоже, вы уже пытались сделать это, добавив scale(1.0) свойство неперекрытого элемента - мое лучшее предположение, что ваш браузер(ы) получил "умный" и обнаружил, что это правило ничего не делает и игнорирует его. Наиболее надежным способом запуска аппаратного ускорения обычно является преобразование по оси Z. Попробуйте изменить трансформацию следующим образом:

@include transform(scale(1.00001), translateZ(0.00001));

вместо того, чтобы использовать значения " 1 "и" 0", я использую бесконечно близкие значения; надеюсь, это предотвратит браузер от "умного" и игнорирования правила.

Я предполагаю, что ваш Sass включает в себя префикс поставщика. Дважды проверьте, что конечный результат включает не только -webkit-transform: и -moz-transform:, но что он также содержит без префикса transform: синтаксис. Если вы хотите быть уверены (для целей отладки), просто введите их вручную:

.usp .icon {
  transform: scale(1.00001), translateZ(0.00001);
  -webkit-transform: scale(1.00001), translateZ(0.00001);
  -moz-transform: scale(1.00001), translateZ(0.00001);
}

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


Ahhh, но вы пробовали

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

http://jsfiddle.net/j04mayvb/4/

enter image description here

Я честно не знаю, почему это работает, но я вижу, что он останавливает мерцание на вашей скрипке в Safari.


ОК!

Итак, проблема, с которой я столкнулся, была в пользовательском всплывающем окне, где у меня был эффект колеса на перекрестной кнопке с помощью CSS-перехода. Но это вызвало проблему мерцания во всплывающем окне.

после посещения различных онлайн-порталов я узнал, что свойство перехода:

webkit-backface-visibility: hidden;

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

webkit-transform: translate3d(0, 0, 0);

но поскольку я использовал его в пользовательское всплывающее окно, которое уже было переведено -50% в y-направлении, чтобы держать его в центре, я был ограничен не использовать его.

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

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

надеюсь, что это поможет любому, кто в этом нуждается. :)


-webkit-transform: translate3d(0, 0, 0);
-webkit-text-stroke: 0.35px;

эти коды написаны для поддержки нескольких браузеров. попробуйте это для Mozila

-moz-transform: translate3d(0, 0, 0);
-moz-text-stroke: 0.35px;

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

в интернете есть множество исправлений для браузеров на основе webkit, но ничего для Firefox.


мы также искали в течение нескольких недель, пытаясь решить эту проблему. Вы можете использовать все виды трюков, как те, которые упомянуты выше, чтобы поместить элемент в свой собственный слой GPU. Но это вызовет текст должны быть преобразованы в Bitmap и поэтому размыто.

в нашем случае проблема возникла из-за oneven пикселей. Когда вы центрируете модальный, используя translate -50% или, возможно, используете % sizes. Дочерние элементы внутри этого контейнера могут получить oneven позиции (в зависимости от ширины / высоты модального). В chrome вы можете просто проверить это на элементе в вычисляемой вкладке. Если есть позиции oneven, вы можете увидеть их "прыжок" при наведении курсора на другой элемент, например, анимированную кнопку css.

когда вы наводите курсор на кнопку css, это не только рендеринг самого элемента, но и других элементов на странице. Из-за позиций oneven вы можете видеть, как элемент прыгает.

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

после нескольких недель поиска ответ на Chrome был довольно простым, теперь мы используем более старые вариант масштабирования: 1.0 вместо translate: (масштаб 1.0). В результате теперь у нас есть четкая и не мерцающая страница.

пример конечного результата со шкалой и не мерцающими кнопками и переходами: