Why does applying '-webkit-backface-visibility: hidden;' fix issues with negative margin transition on on ios / ipad 5.1?

Caroline picture Caroline · Dec 19, 2012 · Viewed 14k times · Source

I have stumbled on a fix for my issue by accident - and I don't like applying fixes I don't understand.

<ul>
  <li><img src="something.jpg" /></li>
  <li><img src="somethingElse.jpg" /></li>
  [+12 more <li>'s]
</ul>

A precis of what I think are the pertinent css styles are:

ul {
  position: absolute;
  list-style-type: none;
  top: 0;
  left: 0;
}
li {
  position: relative;
  height: 900px;
  width: 500px;
  float: left;
}
img {
  display: block;
  margin: 0 auto;
}

The problem: When applying a transition that performs the transition to shift the whole set of images left i.e.:

ul {
  left: -3000px;
}

it works well everywhere except ios 5.1, where it occasionally works, but more usually it initially performs the transition then reverts to showing the last image it 'succesfully' set (e.g. the first image, or an image where the transision set to correctly).

Adding this to the css:

ul {
  -webkit-backface-visibility: hidden;
}

makes everything work properly. Which does not make sense to me, and I only stumbled upon whilst trying to work out how to stop flickering between transitions.

Answer

Caroline picture Caroline · Dec 19, 2012

I think I may actually have worked out the reason for this.

The transition library being used seemed to have a bug in it, meaning that translate() was being used for the transition, not translate3d() despite it being available.

After changing this, the extra css rule:

-webkit-backface-visibility: hidden;

no longer had any effect - the transitions moved the dom node to the correct position without it.

I infer from this that the css rule somehow forced a translate3d() method to be used on the object.

However, to stop the somewhat jagged movement between frames, I still needed to add:

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

I only found this by trial and error: peppering my css with the 'fixes' suggested:

-webkit-perspective: 0;
-webkit-backface-visibility: hidden;
-webkit-transform: translate3d(0,0,0);
visibility:visible;

and ensuring that 'translate3d' was used, I then gradually removed css 'fixes' until it was just '-webkit-transform: translate3d(0,0,0);' was necessary in one place.

So a combination of making the correct call for the animation, and applying a css style in one place made for a much better transition all together :)