Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Relatively positioned elements in scrollable absolutely positioned div "lag behind" on scroll

I have a PhoneGap app that displays a quite long text with headers, tables and images which I am testing on Android.

Everything works fine except for the elements with style position:relative These elements "lag" behind when scrolling, meaning if I scroll the page then those elements start and end scrolling about a quarter of a second later.

The bug happens when combining an absolute div with relative children and a child with overflow:auto. Removing any of those things fixes the bug but I'd prefer do leave it in. Although I'd be willing to remove the table and show it separately (like in a dialog) if I have to.

The bug only presents on the standard Android Browser (and of course my PhoneGap app). So far I've tested it with the following devices:

  • Samsung Galaxy Nexus (4.1.1)
  • Samsung Galaxy S III (4.1.2)

Any help is appreciated but I'd prefer a solution where the HTML and functionality are not changed (or not too much).

after quick scrolling

I created a minimal example showing the bug. Simply open it on your Android and start scrolling and you should see the problem immediately:

<!doctype html>
<html>
<head><meta name="viewport" content="initial-scale=1.0"></head>
<body style="margin:0">

<div style="position:absolute;overflow:auto;top:100px;bottom:100px;width:100%">

  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam a quam arcu. Duis ultrices mollis nibh ut hendrerit. Etiam a interdum metus. Integer volutpat, nibh laoreet euismod suscipit, libero sem iaculis lorem, ut hendrerit magna orci eu elit. Nulla eu ultricies libero. Nulla facilisi. Maecenas nec turpis vitae magna lobortis ornare sit amet ut lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nunc vestibulum lobortis orci, sit amet ornare dui congue nec. Morbi id magna at turpis auctor ultricies. Ut rhoncus quam augue, ut consectetur risus.</p>
  <div style="position:relative;background:red;">relative box<br>moves slower than the other text</div>
  <p>Fusce congue orci a nunc gravida sed pretium lorem convallis. Etiam hendrerit, ligula eget lobortis vestibulum, arcu sapien pharetra magna, auctor suscipit nisl tellus quis lacus. Cras id elit at ante mollis venenatis. Donec eu sollicitudin odio. Aliquam erat volutpat. Cras et tortor sed mi faucibus sagittis non quis metus. Morbi mauris ante, posuere vel rutrum id, mattis id enim. Morbi purus quam, euismod facilisis blandit quis, commodo at justo. Aliquam in fermentum nibh. Curabitur pharetra blandit risus sit amet tristique. Suspendisse potenti. Curabitur interdum eleifend justo, et dapibus justo volutpat sed.</p>          
  <div style="overflow:auto">
    <table>
      <tr><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th></tr>
      <tr><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td></tr>
    </table>
  </div>

</div>
</body>
</html>
like image 214
Thomas Avatar asked Feb 25 '13 17:02

Thomas


3 Answers

In short, the ills you are suffering are common and documented. Elements with overflow:auto or overflow:scroll suffer from paint/reflow/render issues in both desktop and mobile browsers. To compound upon that there are issues in mobile browsers (webkit both on iOS and Android) with regards to not rendering relative and absolute elements if they are "off screen". This can lead to a lag when they are scrolled on screen.

There are a few "hack" shims that you can apply:

element {
    -webkit-overflow-scrolling: touch;
}

element > * {
    -webkit-transform: translateZ(0px);
}

element > * {
    -webkit-transform: translate3d(0,0,0);
}

Some reading for you:

  • http://cantina.co/2012/03/06/ios-5-native-scrolling-grins-and-gothcas/ http://developersday.wordpress.com/2012/08/07/scrollable-divs-rendering-issues-with-css-overflow-auto-or-scroll-iosandroid/

And a snippet I copied from somewhere into my notes and now can't find the source:

Especially on sites that rely heavily on scroll, you might discover that your main content is relying on overflow:scroll. This is a real challenge as this scrolling isn’t GPU accelerated in any way so the content is repainted whenever your user scrolls. You can work around such issues using normal page scroll (overflow:visible) and position:fixed.

like image 181
Nick Sharp Avatar answered Sep 22 '22 11:09

Nick Sharp


I think you have two issues you're trying to fix. The text that slips down below and the lagging scroll speed?

I'm not sure what you're trying to do with the copyright symbol but I wouldn't have a line-height less than 1 or 1em. Try to use a parent element and style the span off of that. You can probably use display:inline-block; vertical-align: middle; on the span to get the desired effect.

<p><span>&copy;</span>Some text</p>

For scrolling it depends on what you're doing. Mobile browsers wait 300ms for <a> tags to see if you are scrolling or clicking a link. It could be related to that. If so, I'd checkout Google FastClick.

Mobile browsers accelerate page scrolling on the body. So using nested divs or position:absolute could keep you from getting the faster scroll speed. In newer versions of Android and iOS you can use -webkit-overflow-scrolling: touch to help but that won't do anything for older phones. I would try not to use position absolute because based on your example it doesn't look like its required, also using nested divs that scroll require some users to use two fingers inside the div to scroll content. I would try to avoid that as well and replace the design with more mobile friendly design patterns like a link that expands content down.

A lot of the scrolling issues have came to light while trying to support position:fixed on mobile if think that might be causing it and you'd like to read about it: http://bradfrostweb.com/blog/mobile/fixed-position/

like image 2
Jesse Avatar answered Sep 18 '22 11:09

Jesse


Remove position:absolute and position:relative , they are absolutely NOT needed for this layout and are causing all your problems.

You can add some margin-top to your body if you wish.

PhoneGap produces some html garbage like that, I hope that you have a fine control of the CSS.

like image 1
George Katsanos Avatar answered Sep 22 '22 11:09

George Katsanos