Позиция исправлена ​​на мобильном устройстве Chrome, вызывая проблемы при прокрутке

Я изучал эту проблему в течение последнего часа и видел похожие вопросы, но я не уверен, что это одна и та же проблема. Вероятно, как-то связано, но ни один из ответов не помог мне решить мою проблему.

Возьмите следующий код:

<html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <style>
            html, body {
                height: 100%;
                margin: 0;
            }

            main {
                background-color: orange;
                height: 1500px;
                margin: 50px;
            }

            footer {
                background-color: green;
                position: fixed;
                height: 50px;
                left: 100px;
                right: 100px;
                bottom: 100px;
            }
        </style>
    </head>
    <body>
        <main></main>
        <footer></footer>
    </body>
</html>

Это трудно отлаживать, потому что я не могу последовательно воспроизвести проблему. Я продолжаю прокручивать вверх и вниз — отображать и скрывать адресную строку в Chrome для Android — в конечном итоге произойдет что-то вроде этого:

введите описание изображения здесь

По какой-то причине footer рисуется в правильном месте (как указано в CSS), но инструменты разработчика Chrome обнаруживают элемент в другом положении (не всегда так, как показано на скриншоте).

Почему это проблема?

Предположим, что у меня есть интерактивные элементы внутри footer, интерактивная область для этих элементов будет находиться в «синей» области, обнаруженной инструментами разработчика Chrome, а не там, где на самом деле рисуется нижний колонтитул (зеленая область), как это должно быть, потому что это то, что пользователь видит.

Мысли?


person rfgamaral    schedule 18.06.2018    source источник
comment
Я рекомендую включить «метатег области просмотра» в заголовок, чтобы правильно масштабировать страницы для мобильных устройств. Затем я бы удалил значение высоты 1500 пикселей и установил его на «min-height: 100%;».   -  person doppler    schedule 18.06.2018
comment
@doppler Тег уже есть, а 1500 пикселей предназначены для имитации контента.   -  person rfgamaral    schedule 18.06.2018
comment
У меня также есть эта проблема, вы можете найти мой пост SO здесь stackoverflow.com/questions/50938106/, и я также сообщил об этом как об ошибке в Chromium здесь bugs.chromium.org /p/chromium/issues/, возможно, присоединитесь к отчету об ошибке, чтобы его заметили. Это определенно ошибка браузера, и кажется, что это происходит только на Android.   -  person James    schedule 20.06.2018
comment
@james.brndwgn Подойдет, вы нашли какой-нибудь обходной путь?   -  person rfgamaral    schedule 20.06.2018
comment
@RicardoAmaral, к сожалению, нет. Поскольку это вызвано сокрытием/отображением адресной строки браузера и влияет только на элементы с фиксированным положением, я не думаю, что есть какой-либо возможный обходной путь - переключение панели на position: absolute, если это вариант, ИЛИ блокировка области просмотра, чтобы адресная строка никогда не скрывалась.   -  person James    schedule 21.06.2018
comment
Единственный надежный обходной путь — запретить Chrome скрывать адрес. Его можно реализовать, как описано в следующей статье StackOverflow: stackoverflow.com/questions/18061308/   -  person knee-cola    schedule 21.06.2018
comment
@james.brndwgn Проверьте мой ответ ниже (опубликованный также в проблеме Chromium) и посмотрите, работает ли обходной путь и для вас :)   -  person rfgamaral    schedule 21.06.2018
comment
@RicardoAmaral Интересно и хорошо. Хотя для меня это непрактично, так как у меня гораздо больше фиксированных элементов на сайте, чем просто нижняя навигация. Я также использую Vue, поэтому прямое манипулирование DOM — не очень хорошая идея, хотя я мог бы сделать это способом Vue. На данный момент, поскольку это довольно серьезная ошибка (в их флагманской ОС и браузере), я надеюсь, что Google быстро ее исправит.   -  person James    schedule 22.06.2018
comment
@james.brndwgn Если это не станет узким местом в производительности, вы можете просто создать директиву и применить ее ко всем фиксированным элементам. Не то чтобы непрактично. Когда Google решит проблему, вы просто удалите директиву. Помните, что Google может исправить ошибку, но у некоторых людей могут не быть автоматические обновления в их браузере.   -  person rfgamaral    schedule 22.06.2018
comment
похоже, это должно быть исправлено в последней версии Chrome - v68 bugs.chromium .org/p/chromium/issues/detail?id=848122   -  person ashutosh    schedule 09.08.2018


Ответы (1)


EDIT: я оставляю код ниже здесь, но обнаружил, что он работает не так, как я ожидал. Это работало во время моего первоначального тестирования, но наш QA обнаружил, что на самом деле это не решило проблему, с которой мы столкнулись. Насколько я знаю, сейчас нет обходного пути, и нам нужно подождать, пока команда Chromium исправит выдать на их стороне.

НЕРАБОЧЕЕ РЕШЕНИЕ

Возможно, я только что нашел обходной путь для этой ошибки Chromium.

Я тестирую это на Pixel 2 с последней версией Chrome, не уверен, насколько хорошо это будет работать на более дешевых устройствах. Это немного уродливо, но, кажется, это работает для меня.

Что я сделал, так это заменил оскорбительный элемент самим собой (вынуждая изменить макет браузера) в событии touchend. Это идеально, потому что проблема существует только на мобильных устройствах, а touchend не существует в настольных версиях.

const body = document.getElementsByTagName('body');
const button = document.getElementsByTagName('button');
const footer = document.getElementsByTagName('footer');

function randomColor() {
  button[0].style.backgroundColor =
    `hsla(${Math.random() * 360}, 100%, 50%, 1)`;
}

window.addEventListener('touchend', function() {
  body[0].replaceChild(footer[0], footer[0]);
}, false);
* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  margin: 0;
}

main {
  background-color: orange;
  height: 3000px;
  margin: 10px;
}

footer {
  border: 2px solid green;
  background-color: greenyellow;
  display: flex;
  justify-content: center;
  align-items: center;
  position: fixed;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 100px;
}

button {
  border: 2px solid black;
  background-color: white;
  cursor: pointer;
  width: 50%;
  height: 70%;
}
<main></main>
<footer>
  <button onclick="randomColor()">CLICK ME!</button>
</footer>

person rfgamaral    schedule 21.06.2018