Относительно расположенные элементы в прокручиваемом абсолютно позиционированном div "отстают" от прокрутки

У меня есть приложение PhoneGap, которое отображает довольно длинный текст с заголовками, таблицами и изображениями, которые я тестирую на Android.

Все работает отлично, за исключением элементов со стилем position:relative Эти элементы "отстают" при прокрутке, то есть, если я прокручиваю страницу, то эти элементы начинают и заканчивают прокрутку примерно через четверть секунды позже.

Ошибка возникает при объединении абсолютного div с относительными дочерними элементами и дочернего с overflow:auto. Удаление любой из этих вещей исправляет ошибку, но я бы предпочел оставить ее. Хотя я бы хотел удалить таблицу и показать ее отдельно (например, в диалоговом окне), если мне нужно.

Ошибка отображается только в стандартном Android-браузере (и, конечно же, в приложении PhoneGap). До сих пор я тестировал его со следующими устройствами:

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

Любая помощь приветствуется, но я бы предпочел решение, в котором HTML и функциональность не изменены (или не слишком).

after quick scrolling

Я создал минимальный пример, отображающий ошибку. Просто откройте его на своем Android и начните прокрутку, и вы сразу увидите проблему:

<!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>

Ответы

Ответ 1

Короче говоря, болезни, которые вы страдаете, распространены и документированы. Элементы с overflow:auto или overflow:scroll страдают от проблем с краской /reflow/render как в настольных, так и в мобильных браузерах. Чтобы усугубить это, в мобильных браузерах есть проблемы (webkit как на iOS, так и на Android), поскольку они не отображают относительные и абсолютные элементы, если они "вне экрана". Это может привести к задержке при прокрутке на экране.

Есть несколько "прокладок", которые вы можете применить:

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

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

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

Некоторое чтение для вас:

И фрагмент, который я скопировал откуда-то в свои заметки и теперь не могу найти источник:

Особенно на сайтах, которые сильно зависят от прокрутки, вы можете обнаружить что ваш основной контент полагается на переполнение: прокрутка. Это настоящая вызов, поскольку эта прокрутка не ускоряется GPU, так что содержимое перерисовывается всякий раз, когда ваш пользователь прокручивается. Вы можете работать такие проблемы, используя обычную прокрутку страницы (переполнение: видимое) и положение:. фиксированный

Ответ 2

Я думаю, у вас есть две проблемы, которые вы пытаетесь исправить. Текст, который проскальзывает ниже и скорость задержки прокрутки?

Я не уверен, что вы пытаетесь сделать с символом авторского права, но я бы не имел line-height меньше 1 или 1em. Попытайтесь использовать родительский элемент и отделите его. Вы можете, вероятно, использовать display:inline-block; vertical-align: middle; на пролете, чтобы получить желаемый эффект.

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

Для прокрутки это зависит от того, что вы делаете. Мобильные браузеры ждут 300ms для тегов <a>, чтобы увидеть, прокручиваетесь ли вы или щелкните ссылку. Это может быть связано с этим. Если да, я бы проверил Google FastClick.

Мобильные браузеры ускоряют прокрутку страницы на теле. Таким образом, использование вложенных div или position:absolute может помешать вам получить более быструю скорость прокрутки. В более новых версиях Android и iOS вы можете использовать -webkit-overflow-прокрутку: коснитесь, чтобы помочь, но это ничего не сделает для старых телефонов. Я бы постарался не использовать абсолютную позицию, потому что на основе вашего примера она не выглядит так, как требуется, а также с помощью вложенных div, которые прокрутки требуют от некоторых пользователей использовать два пальца внутри div для прокрутки содержимого. Я попытался бы избежать этого и заменить дизайн более мобильными конструктивными шаблонами, такими как ссылка, которая расширяет содержание.

Многие проблемы с прокруткой выявились при попытке поддерживать position:fixed на мобильном телефоне, если вы думаете, что это может вызвать его, и вы хотели бы прочитать об этом: http://bradfrostweb.com/blog/mobile/fixed-position/

Ответ 3

Удалите position:absolute и position:relative, они абсолютно НЕ нужны для этого макета и вызывают все ваши проблемы.

Вы можете добавить margin-top к своему телу, если хотите.

PhoneGap создает некоторый html-мусор, я надеюсь, что у вас есть прекрасный контроль над CSS.

Ответ 4

На самом деле для него существует простое исправление CSS, добавляя position:relative к вашим абзацам, чтобы решить проблему.

Попробуйте следующее:

<!doctype html>
<html>
<head><meta name="viewport" content="initial-scale=1.0">
<style>
p{ position:relative;}
</style>
</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>