Вычисление высоты просмотра в Chrome Android с помощью CSS

Итак, я заметил, что мобильный Chrome вычисляет адресную строку в высоту области просмотра. Из-за этого использование height: 100vh для элемента не работает, потому что при height: 100vh адресной строки высота области просмотра изменяется.

На самом деле мне удалось найти вопрос с такой же проблемой здесь, на ios, но после дальнейшего изучения я понял, что это происходит во всех мобильных браузерах Chrome. Когда адресная строка прокручивается из области просмотра, а затем снова, когда прокручивается в область просмотра, высота области просмотра изменяется.

Это приводит к тому, что любой элемент, использующий vh пересчитывает, что заставляет страницу перемещаться. Это очень раздражает при использовании фонового изображения, потому что оно вызывает изменение размера изображения при прокрутке.

Вот код и пример

   .jumbotron {
        background-image: url(http://example.com/image.png);
        background-size: cover;
        background-position: top;
        background-repeat: no-repeat;
        height: 100vh;
    }

Вы сможете увидеть проблему только при прокрутке вверх и вниз с помощью мобильного Chrome.

Мой вопрос, я хотел бы знать, есть ли способ обойти это или, если нет, как рассчитать полную высоту на мобильном Chrome, не вызывая скачок страницы (CSS или JS).

http://s.codepen.io/bootstrapped/debug/qadPkz


Обновление: Итак, что касается использования jquery, то, что я придумал, похоже, работает довольно хорошо:

function calcVH() {
    $('.jumbotron').innerHeight( $(this).innerHeight() );
}
$(window).on('load resize orientationchange', function() {
  calcVH();
});

Демо рабочего примера выше

Я хотел бы иметь возможность сделать это без JavaScript, хотя, если у кого-то есть альтернатива CSS, которая, как он знает, работает.

Ответ 1

Вот с чем я пошел:

HTML

<div id="selector"></div>

CSS

#selector {
   height: 100vh;
}

Jquery

function calcVH() {
    $('#selector').innerHeight( $(this).innerHeight() );
}
(function($) { 
  calcVH();
  $(window).on('orientationchange', function() {
    calcVH();
  });
})(jQuery);

PURE JS (NO JQUERY)

function calcVH() {
  var vH = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
  document.getElementById("selector").setAttribute("style", "height:" + vH + "px;");
}
calcVH();
window.addEventListener('onorientationchange', calcVH, true);

Просто измените #selector на любой из селекторов css. Если вы используете чистую версию js, вам нужно использовать идентификатор, если вы не измените .getElementByID на .getElementsByClassName.

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

Надеюсь, это скоро будет исправлено, поэтому решение javascript не понадобится. Кроме того, я попытался добавить событие изменения размера, если ширина браузера изменится, но, увидев этот вопрос, я удалил его из своего ответа. Если вы хотите попробовать использовать это, просто измените приведенное выше:

Jquery

function calcVH() {
    $('#selector').innerHeight( $(this).innerHeight() );
}
(function($) { 
  calcVH();
  $(window).on('orientationchange resize', function() {
    calcVH();
  });
})(jQuery);

$(window).on('resize orientationchange', function() {

PURE JS (NO JQUERY)

function calcVH() {
  var vH = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
  document.getElementById("selector").setAttribute("style", "height:" + vH + "px;");
}
calcVH();
window.addEventListener('onorientationchange', calcVH, true);
window.addEventListener('resize', calcVH, true);

Ответ 2

Я пробовал каждое предложение... но ничего не работает для меня. Либо с Chrome, либо с IOS.

Но тогда... У меня была идея!

1. Вы можете оставить стандартную запись в голове

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

2. Напишите JS в ноге (убедитесь, что jQuery знает о ваших элементах) сайта, например

<script type="text/javascript" charset="utf-8">
  (function() {
    function size() {
      // you can change here what you prefer
      if (/android|webos|iphone|ipad|ipod|blackberry|nokia|opera mini|opera mobi|skyfire|maemo|windows phone|palm|iemobile|symbian|symbianos|fennec/i.test(navigator.userAgent.toLowerCase())) {
        var theminheight = Math.min(document.documentElement.clientHeight, window.screen.height, window.innerHeight);
        //now apply height ... if needed...add html & body ... i need and i use it
        $('html body #yourelementofchoise').css('height', theminheight);
      }
    }
    window.addEventListener('resize orientationchange', function() {
      size();
    }, false);
    size();
  }());
</script>

3. Нет больше Навигационная панель хрома или что-то другое будет мешать вашему выходу или тому, что вы хотите видеть

Я действительно надеюсь, что это поможет кому-то!

Возможно, это всего лишь шаблон, делающий это намного больше.

Ответ 3

Надеюсь, что этот взлом поможет Chrome в телефонах Android, пока у нас не будет хорошего решения

@media all and (-webkit-min-device-pixel-ratio: 0) and (min-resolution: 0.001dpcm) and @media (max-width: 480px) {
   height: calc(100vh - 56px);
}