Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS3 transition/transform/translate3d causes severe flicker on first or last "frame" of the transition (on an iPad)

All,

I'm working on a web app specifically for the iPad, and I'm using a CSS3 transition to animate a div (move it from left to right).

My class looks like this:

.mover {
    -webkit-transition:all 0.4s ease-in-out;
}

When the user clicks a button, I do this:

var s = "translate3d(" + newPosition + "px, 0, 0)";
$('.mover ').css('-webkit-transform', s);

This works great EXCEPT the FIRST time the user triggers the transition; the first time, there's a very noticeable flicker.

I realize I don't need to use translate3d since I'm only moving the div left and right, but, as I understand it, this forces the iPad to use GPU acceleration. (Is this correct?)

Many thanks in advance!

[UPDATE]

I was a little ambiguous about the "flicker". In short - I've been experimenting with a wide variety of CSS3 transitions (specifically on the iPad), and consistently - I've noticed a distinct flicker at the start or end of the transition.

In other words, the transitions themselves are VERY smooth. However, depending on the precise settings, there's a noticeable flicker just before the transition begins or ends.

Here's another example: I have three photos (PNGs) stacked on top of each other.

The bottom PNG has opacity=1.0, the top 2 have opacity=0.0. Using -webkit-keyframes, I'm able to get silky smooth transitions as the photos fade in and out. When the animation ends, the bottom photo ends at opacity=1.0, the top two at opacity=0.0. (That should be their final state).

However, just as the animation ends, the bottom photo flickers. It's as though the browser is forces to redraw/repaint the screen, and that takes a few fractions of a second.

It's bad enough to spoil the effect, and render then transitions unuseable. (On my iMac it is almost, but not quite, imperceptible. On the iPad, it's unmissable).

like image 558
mattstuehler Avatar asked Apr 28 '11 05:04

mattstuehler


4 Answers

I was dealing with the same issue, and I found the solution here on SO: iPhone WebKit CSS animations cause flicker

It's as simple as adding

-webkit-backface-visibility: hidden;

and possibly

-webkit-perspective: 1000;

To each animated object. It worked for me, hope this helps for you too

like image 197
Bob Vork Avatar answered Oct 17 '22 06:10

Bob Vork


All,

I'm not positive that this is the answer (especially because the flicker itself seems a little unpredictable), but anecdotally, this seems to get rid of it...

Anyway, here's what I was doing:

.mover {
    -webkit-transition:all 0.4s ease-in-out;
}

var s = "translate3d(" + newPosition + "px, 0, 0)";
$('.mover ').css('-webkit-transform', s);

Often, the FIRST time this was executed, I'd see a flicker before the animation begins. Subsequent calls would animate smoothly.

What I inferred was that, if the 3d coordinates were not set before calling the animation, you'd see a flicker. The first call sets those coordinates, so subsequent calls would animate smoothly.

So - I tried setting the 3d coordinates of the div first (essentially, when I'm first building the screen - i.e., initialization), before any animations are ever triggered.

So, thereafter - when a 3d animation is called for, the div/element's starting 3d coordinates have already been established.

That seems to eliminate the flickering.

As I said - I'm not sure if this is a robust, reliable fix, but it certainly has eliminated the problem in my current projects.

Good luck.

like image 34
mattstuehler Avatar answered Oct 17 '22 05:10

mattstuehler


We solved many flickering and font problems by fixing the viewport.

Previously we had content going off the page (a sliding div) and the device seemed to go into conniptions when the viewport wasn't fixed, having to process data off the screen in combination with the zoom-a-bility of the displayed content.

This tag in the head solved our problems.

<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
like image 5
xiatica Avatar answered Oct 17 '22 04:10

xiatica


Try

.mover {
    position:absolute;
    -webkit-transition:-webkit-transform 0.4s ease-in-out;
} 

but, as I understand it, this forces the iPad to use GPU acceleration

Both translate() and translate3d() create stacking context and may use layers - texture buffers in terms of GPU. So I don't think that they really make any difference in terms of acceleration.

like image 1
c-smile Avatar answered Oct 17 '22 04:10

c-smile