iOS scrolling bug


When Apple released iOS 5 last year, one of the improvements included in Mobile Safari was the inclusion of support for scrolling of block elements with the CSS overflow:auto oroverflow:scroll declarations. In addition, support for fancy and fast bounce-scroll behavior is provided with the inclusion of the -webkit-overflow-scrolling: touch vendor-specific declaration.

The inclusion of scrolling on clipped elements is great and goes a ways towards making it much easier to layout HTML5 pages and apps in a consistent manner, and closes the gap a bit between web and native behaviors. And it’s easy to implement.

For example, to add scrolling on an element with class="scrolling-element":

.scrolling-element {
   overflow: auto; /* or overflow: scroll, if that's your thing */
   -webkit-overflow-scrolling: touch;

Fast scrolling, broken rendering

Unfortunately, Apple released a buggy implementation of -webkit-overflow-scrolling: touch. The problem is seems pretty awful at first: if you use the new native scrolling behavior on elements that use or contain children withposition:relative, you may end up with some pretty gnarly rendering areas. This is particularly true for stuff that gets rendered off-screen.

Lucky for us, there is relatively (ahem) painless workaround. If you force Mobile Safari to use hardware acceleration when drawing the positioned elements, the rendering errors disappear. How do you do that? With a little 3D magic, via a no-move translation with this declaration: -webkit-transform: translate3d(0,0,0). Sprinkling this 3D fairy dust on your elements with position:relative and your rendering issues will vanish.

.scrolling-element-class {
   overflow: auto;
   -webkit-overflow-scrolling: touch;

.scrolling-element-class .child-element {
   position: relative;
   -webkit-transform: translate3d(0,0,0);

One thing I have found is that sometimes, you need to apply the hardware acceleration hack to all of the child elements inside the scroller. This turned out to be true on a very complicated faux table in our really big HTML5 iPad app. The solution there was to use a scope universal selector. This isn’t the most performant selector, but it gets the job done in a way that working with the individual elements just didn’t cut it.

.scrolling-element-class * {
   -webkit-transform: translate3d(0,0,0);

Update: I have found since writing this that even the hardware acceleration hack doesn’t cure all rendering ills. On the aforementioned complex layout, which for various reasons mimics a table, some of the elements in the cells were rendering incorrectly even with translate3d(). The solution in this case was to fix the height of the elements. This is not ideal in all situations, of course, and I’ll be looking for alternatives in the future. Also, iOS 5.1 does not appear to fix the scrolling issues.


Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:


Для комментария используется ваша учётная запись Выход /  Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s