175

Possible Duplicate:
iphone webkit css animations cause flicker

For some reason, right before my animation of the webkit-transform property occurs, there is a slight flicker. Here is what I am doing:

CSS:

#element {
    -webkit-transition: -webkit-transform 500ms;
}

JavaScript:

$("#element").css("-webkit-transform", "translateX(" + value + "px)");

Right before the transition takes place, there is a flicker. Any idea why this is, and how I could fix the problem?

Thanks!

Update: this only occurs in Safari. It does not happen in Chrome, although the animation does work.

Community
  • 1
  • 1
devongovett
  • 4,850
  • 5
  • 34
  • 35

8 Answers8

297

The solution is mentioned here: iPhone WebKit CSS animations cause flicker.

For your element, you need to set

-webkit-backface-visibility: hidden;
Community
  • 1
  • 1
rpitting
  • 3,329
  • 1
  • 19
  • 10
  • 11
    My transitions was affecting other elements on the site and I ended up by having to add the rule to all elements on the site. – mlunoe Jan 10 '13 at 13:53
  • Worked for me as well. I had a hidden menu that was pushing the content down with a CSS animation when it was shown. Applying the above rule to my main content div that followed the hidden menu fixed my issue without drastically affecting performance. NB: When I applied it to my global HTML rule it made the CSS animation quite a bit worse, beware! – Primus202 Apr 08 '13 at 23:03
  • 3
    Using a wildcard selector for this property actually caused additional flickering from other elements. My working solution was to selectively apply the property to elements that were being translated. – hlfcoding Sep 17 '13 at 03:19
  • 1
    had to add it to parent container too. – chovy Oct 01 '13 at 06:46
  • I think my issue (albeit an intermittent one) was fixed by the universal selector – lol Dec 27 '13 at 23:27
  • 4
    Use -webkit-backface-visibility: hidden; wisely! I just tried to use it on a scrollable list with images and it caused serious framerate drops. – mimimimichael Apr 13 '14 at 21:35
  • I would caution against using -webkit-backface-visibility: hidden; as it can cause rendering glitches and make transformed elements appear extremely blurry. I have had some success with using this, but often times it doesn't actually work anyway or I have to go through a lengthy trial and error process to find which elements I have to apply it on. Applying it on all (*) elements has always given me rendering issues with Chrome and I have little hope those will get fixed any time soon. – aphax Jan 14 '15 at 12:09
  • 1
    PLEASE do not use a wildcard to apply the property to your entire site. Use it sparingly on the troublesome elements. It can drastically reduce performance. – Primus202 Sep 08 '15 at 23:47
  • I am trying but it is not working for me. Here is a code snippet: http://www.codeply.com/go/g7Zp98paz5 – Fran_gg7 Nov 21 '16 at 13:42
  • None of the answers here worked for me. Not only was I transitioning but I was also changing the `overflow` property. [This answer about -webkit-overflow-scrolling](https://stackoverflow.com/a/24907169/1408717) was the solution to my problem. – Aust Jul 20 '17 at 22:45
94

The rule:

-webkit-backface-visibility: hidden;

will not work for sprites or image backgrounds.

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

screws up backgrounds that are tiled.

I prefer to make a class called no-flick and do this:

.no-flick{-webkit-transform:translate3d(0,0,0);}
ablemike
  • 3,384
  • 3
  • 22
  • 21
  • 6
    You are right, the backface-visibility fix does not work on image backgrounds. Thanks. – ppcano Oct 06 '12 at 12:15
  • 5
    Note, when using translate3d(0,0,0) _anywhere_ Chrome now breaks any background-position: cover that you may or may not have. – pyronaur Jul 31 '13 at 10:49
  • 3
    This is also the way to go with SVGs. – Dillon Sep 11 '15 at 16:14
  • I ran into a similar issue... its not exactly the same, however I could see it being relevant in some cases. I had a card flip with a background svg on the backface that was backface-visibility: hidden. On webkit, the background would show until the flip finished, then disappear. My transform was : translateY(180deg). To fix the disappearance in webkit I had to apply, transform: translateZ(-1px) translateY(180deg);, this resolved the disappearance issue. A z-index issue, but of the 3d space, not dom layering. Tricky. – KazaJhodo Oct 26 '17 at 01:43
55

Add this css property to the element being flickered:

-webkit-transform-style: preserve-3d;

(And a big thanks to Nathan Hoad: http://nathanhoad.net/how-to-stop-css-animation-flicker-in-webkit)

Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
Michael Bar-Sinai
  • 2,729
  • 20
  • 27
  • this is great - it didn't solve the problem, but it did force my code to be more strict and made tracking down the actual issue easy to find. – itsclarke Mar 24 '21 at 20:10
21

For a more detailed explanation, check out this post:

http://www.viget.com/inspire/webkit-transform-kill-the-flash/

I would definitely avoid applying it to the entire body. The key is to make sure whatever specific element you plan on transforming in the future starts out rendered in 3d so the browsers doesn't have to switch in and out of rendering modes. Adding

-webkit-transform: translateZ(0) 

(or either of the options already mentioned) to the animated element will accomplish this.

Dan Tello
  • 1,517
  • 1
  • 10
  • 10
17

I had to use:

-webkit-perspective: 1000;
-webkit-backface-visibility: hidden;    

on the element, or I would still get a flickr the first time a transition occurred after page load

Kevin H
  • 179
  • 1
  • 4
14

I found that applying the -webkit-backface-visibility: hidden; to the translating element and -webkit-transform: translate3d(0,0,0); to all its children, the flicker then disappears

Adam Carter
  • 4,741
  • 5
  • 42
  • 103
7

Trigger hardware accelerated rendering for the problematic element. I would advice to not do this on *, body or html tags for performance.

.problem{
  -webkit-transform:translate3d(0,0,0);
}
dontmentionthebackup
  • 2,775
  • 1
  • 21
  • 18
1

Both of the above two answers work for me with a similar problem.

However, the body {-webkit-transform} approach causes all elements on the page to effectively be rendered in 3D. This isn't the worst thing, but it slightly changes the rendering of text and other CSS-styled elements.

It may be an effect you want. It may be useful if you're doing a lot of transform on your page. Otherwise, -webkit-backface-visibility:hidden on the element your transforming is the least invasive option.