logo

Исправляем обрезание контейнера на 100vh в Chrome Mobile

Быстрый ответ

Для решения проблемы с высотой 100vh на мобильных устройствах в браузере Chrome используйте JavaScript для обновления CSS-переменной на основе свойства window.innerHeight. Этот подход адаптирует высоту элемента к изменениям, вызванным появлением или скрытием адресной строки.

JS
Скопировать код
function adjustViewportHeight() {
  // Приводим в соответствие высоту видимой области
  document.documentElement.style.setProperty('--viewport-height', `${window.innerHeight}px`);
}

adjustViewportHeight();

// Обрабатываем изменение ориентации экрана
window.addEventListener('orientationchange', adjustViewportHeight);

В вашем CSS-файле примените новую переменную следующим образом:

CSS
Скопировать код
.element {
  height: var(--viewport-height);
}

Так элемент .element будет иметь высоту, соответствующую реальной высоте видимой области экрана.

Разбираемся с проблемой высоты видимой области

Мобильные браузеры, как Chrome, при прокрутке прячут адресную строку, что вносит искажения в значение 100vh. На десктопе 100vh точно соответствует полной высоте видимой области экрана, в мобильных браузерах же 100vh учитывает место, занимаемое адресной строкой, делая это значение непостоянным.

Решаем проблему с помощью CSS и JavaScript

Нам понадобятся следующие инструменты:

  1. Функция calc() в CSS: Дает возможность динамически высчитывать высоту.
  2. CSS Variables (--vh): Used for storing the viewport height changes and applying them within CSS.
  3. События JavaScript: Обработка событий resize или orientationchange помогает поддерживать актуальность размеров.

Следуйте этим шагам:

JS
Скопировать код
// Функция устанавливает динамическую высоту видимой области
function setViewportProperty() {
  let vh = window.innerHeight * 0.01;
  document.documentElement.style.setProperty('--vh', `${vh}px`);
}

// Реагируем на изменение размеров экрана
window.addEventListener('resize', setViewportProperty);

// Выполняем инициализацию
setViewportProperty();

Теперь добавим в CSS следующие строки:

CSS
Скопировать код
.element {
  min-height: calc(var(--vh, 1vh) * 100);
}

Благодаря этому содержимое элемента будет корректно адаптироваться, учитывая занимаемое или освобождаемое адресной строкой место.

Решаем проблему кросс-браузерной совместимости

Особенности мобильного Safari

В Safari на iOS высота 100vh может включать адресную строку, поэтому она не соответствует реальному размеру видимой области экрана. Используйте для основного контейнера значение height: 100% и установите высоту элементам html и body как 100%, чтобы избежать ошибок. Для Safari примените в CSS -webkit-fill-available:

CSS
Скопировать код
.element {
  height:100vh; /* Надёжный вариант в качестве резервного */
  height: -webkit-fill-available; /* Специально для Safari */
}

Настройка единиц высоты

Использование различных единиц видимой области

Возможно, вы захотите попробовать разные единицы для размера видимой области. Обратите внимание, что 100vh может быть ненадежным из-за изменений размера адресной строки. Вместо него можно использовать 100%, но при этом необходимо корректно передавать высоту элементам html и body. Альтернативные варианты, такие как 100dvh, находятся пока на стадии обсуждения.

Использование API VisualViewport

Разработчики из команды Chrome активно работают над устранением этих проблем посредством API VisualViewport, которое позволит точнее контролировать размеры видимой области, учитывая такие переменные факторы, как виртуальная клавиатура и адресная строка.

Визуализация

Приведем наглядное сравнение:

Без адресной строки:
💧💧💧💧💧 (Стакан полный: 100vh – полная высота экрана)

С адресной строкой (отмечено 🧊):
💧💧🧊💧💧 (Использование снижено: <100vh – пространство занимает адресная строка)

Высота видимой области изменяется в зависимости от того, отображается адресная строка или скрыта.

Задача: держать стакан полным (🥤)
Решение на CSS: корректируем высоту с помощью JS, учитывая появление/скрытие адресной строки (🧊).

Применение такого подхода обеспечит непрерывное отображение вашего контента для пользователей, несмотря на изменения размеров адресной строки.

Дополнительные советы и распространенные ошибки

Работа в горизонтальном режиме

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

Учет вырезов на экране

На устройствах с вырезами на экране содержимое не должно обрезаться этими вырезами. Применяйте функции env() и constant() в CSS для обеспечения корректного отображения содержимого.

Приспособление к обновлениям браузера

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

Полезные материалы

  1. The trick to viewport units on mobile | CSS-Tricks — Работа с единицами vh на мобильных устройствах.
  2. Introducing visualViewport | Blog | Chrome for Developers — Адаптация Chrome к API VisualViewport.
  3. VisualViewport – Web APIs | MDN — Официальная документация MDN по API VisualViewport.
  4. html – CSS3 100vh not constant in mobile browser – Stack Overflow — Обсуждение проблемы 100vh на мобильных устройствах на сообществе Stack Overflow.
  5. Can I use... Support tables for HTML5, CSS3, etc — Таблицы совместимости браузеров для единиц видимой области.