Coder Perfect

HTML elements disappear and return with a delay when scrolling on an iPad Safari page.


I’m currently working on an iPad Safari online application utilizing HTML5 and jQuery. I’m having trouble with large scroll zones that cause offscreen components to appear after a delay when I scroll down to them.

What I mean is that if I have a row of photos (or even a div with a gradient) that is offscreen, the anticipated behavior is for the element to show on screen when I scroll down (or up) to it.

The element, however, does not display until I remove my finger from the screen and the scroller has completed all of its movements.

This is generating a glaring issue for me, making the entire thing appear choppy when it isn’t. I’m sure the iPad Safari is attempting to save memory in some way. Is there a way to keep this choppy-ness from occurring?

Furthermore, what is the purpose of iPad Safari?

Asked by codeBearer

Solution #1

You must persuade the browser to make better advantage of hardware acceleration. You can do this with a three-dimensional transform that is empty:

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

This is especially important for child components with a position:relative; declaration (or, just go all out and do it to all child elements).

It is aot a guaranteed fix, but it is fairly successful most of the time.

Hat tip: iOS 5 Native Scrolling–Grins & Gotchas

Answered by Colin Williams

Solution #2

Previously, I used translate3d. It had unfavorable outcomes. Basically, it would chop off and not render elements that were offscreen, until I interacted with them. So, basically, in landscape orientation, half of my site that was offscreen was not being shown. This is a iPad web application, owing to which I was in a fix.

While applying 3d to similarly positioned elements solved the problem for those elements, rendering for other elements ceased once they were offscreen. Unless I reloaded the page, the elements that I couldn’t interact with (artwork) would never render again.

The complete solution:

*:not(html) {
    -webkit-transform: translate3d(0, 0, 0);

Even though it wasn’t the most “efficient” solution, it was the only one that worked. When using -webkit-overflow-scrolling: touch, Mobile Safari does not render offscreen elements or renders them incorrectly. Unless any other items that might fall offscreen due to the scroll have a translate3d applied to them, they will be chopped off after scrolling.

(This is the entire response to my query.) Colin Williams’ answer was originally marked as the correct answer because it assisted me in completing the solution. After roughly 2.5 years of asking the query, a community member, @Slipp D. Thompson, changed it and told me I was abusing SO’s Q & A format. He also told me to post this as a separate response. Thank you, Colin Williams! The answer, as well as the post you linked to, inspired me to experiment with CSS. So, once again, thank you, and I hope this aids some other lost person. This was quite beneficial to me.)

Answered by codeBearer

Solution #3

In my scenario, targeting all components except html: *:not(html) produced issues with other elements. It changed the stacking context, which resulted in several z-indexes being broken.

We should try to target the right element and use -webkit-transform: translate3d(0,0,0) solely on that element.

The function 3D(0,0,0) does not always work. To target the right element, we can use the following method:

@keyframes redraw{
    0% {opacity: 1;}
    100% {opacity: .99;}

/* iOS redraw fix */
animation: redraw 1s linear infinite;

Answered by Guillaume Gautier

Solution #4

If the 3d doesn’t seem to be working, try adding perspective. It is always effective for me.

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

Increase the speed of your website with hardware-accelerated CSS.

Answered by Fellipe Lima

Solution #5

For some reason, adding -webkit-transform: translate3d(0,0,0) to a static element does not work for me.

I use this property in a dynamic way. When a page is scrolled, for example, I use -webkit-transform: translate3d(0,0,0) on an element. After that, I reset this property, which is -webkit-transform: none, after a short interval. This strategy appears to be effective.

Colin Williams, thank you for putting me in the proper route.

Answered by Alexander Poleschuk

Post is based on