Back

5 мелких проблем мобильного веба (и как их исправить)

5 мелких проблем мобильного веба (и как их исправить)

Вы протестировали свою вёрстку на всех контрольных точках, ваша адаптивная сетка выглядит чисто, и всё отлично работает в Chrome DevTools. Затем вы открываете сайт на реальном телефоне, и что-то слегка, упорно не так. Это мелкие проблемы мобильного веба — небольшие баги, которые не ломают страницу, но незаметно ухудшают пользовательский опыт.

Вот пять проблем, которые регулярно встречаются в реальных проектах, и современные способы их исправления.

Ключевые выводы

  • 100vh выходит за границы на мобильных браузерах с динамическими элементами интерфейса. Используйте 100svh как стабильное значение по умолчанию, или 100dvh для макетов, которые должны изменять размер при скрытии и отображении элементов браузера.
  • Элементы, зафиксированные внизу, могут быть скрыты безопасными зонами устройства. Добавьте viewport-fit=cover и используйте env(safe-area-inset-bottom), чтобы сохранить их видимыми.
  • iOS Safari автоматически увеличивает масштаб на полях ввода с размером шрифта меньше 16px. Установите font-size: 16px или больше на всех полях формы вместо отключения масштабирования пользователем.
  • Цепочка прокрутки пропускает события прокрутки из модальных окон. Примените overscroll-behavior: contain к прокручиваемому контейнеру — JavaScript не требуется.
  • Слишком маленькие области нажатия приводят к промахам или ошибочным нажатиям. Стремитесь к целям касания около 44×44px, используя padding для расширения области нажатия.

1. Полноэкранные макеты ломаются из-за 100vh

Симптом: Полноэкранный hero-блок или модальное окно слегка слишком высокое в iOS Safari, что приводит к обрезанию контента или появлению полосы прокрутки.

Почему это происходит: 100vh рассчитывается относительно полной высоты viewport, игнорируя динамические элементы интерфейса браузера (адресную строку и элементы навигации). Когда эти элементы видимы, 100vh выходит за границы.

Решение: Используйте новые единицы измерения viewport в CSS. Для большинства полноэкранных макетов 100svh (small viewport height — высота малого viewport) является стабильным выбором, поскольку представляет видимую область с присутствующим интерфейсом браузера. Используйте 100dvh, когда хотите, чтобы макет динамически изменял размер при скрытии и отображении элементов браузера. Современная поддержка этих единиц в браузерах широко доступна, как показано на https://webstatus.dev/features/viewport-unit-variants.

.hero {
  height: 100svh; /* stable default */
}

2. Нижний фиксированный интерфейс скрывается за безопасными зонами устройства

Симптом: Липкий футер, нижняя панель навигации или кнопка действия частично скрыты индикатором Home на iPhone или другими безопасными зонами устройства.

Почему это происходит: Фиксированные элементы, позиционированные с bottom: 0, располагаются вплотную к краю viewport, а не к безопасной зоне устройства. На устройствах с индикаторами Home или закруглёнными углами системный интерфейс может перекрывать элемент.

Решение: Добавьте viewport-fit=cover в ваш meta-тег viewport, затем используйте переменные окружения безопасной зоны CSS, такие как env(safe-area-inset-bottom), чтобы сдвинуть элемент вверх.

<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
.bottom-nav {
  padding-bottom: env(safe-area-inset-bottom);
}

3. iOS увеличивает масштаб на полях ввода формы

Симптом: Нажатие на <input> в iOS Safari вызывает неожиданное увеличение масштаба страницы, нарушая макет.

Почему это происходит: iOS Safari автоматически увеличивает масштаб, когда размер шрифта поля ввода меньше 16px, рассматривая это как помощь в читаемости.

Решение: Установите font-size: 16px (или больше) на всех полях ввода. Не отключайте масштабирование через user-scalable=no — это вредит доступности. Заодно используйте inputmode для запроса нужной клавиатуры, autocomplete для уменьшения трения и enterkeyhint для обозначения клавиши возврата.

<input
  type="email"
  inputmode="email"
  autocomplete="email"
  enterkeyhint="done"
  style="font-size: 16px;"
/>

4. Прокрутка утекает из модальных окон и выдвижных панелей

Симптом: Когда пользователь прокручивает содержимое внутри модального окна или нижней панели и достигает конца, страница за ним тоже начинает прокручиваться.

Почему это происходит: Это цепочка прокрутки — браузер передаёт события прокрутки родительскому элементу, когда дочерний прокручиваемый контейнер достигает своей границы.

Решение: Примените overscroll-behavior: contain к прокручиваемому контейнеру. Современная поддержка браузерами широка, включая Safari 16 и более поздние версии, как показано на https://webstatus.dev/features/overscroll-behavior.

.modal-body {
  overflow-y: auto;
  overscroll-behavior: contain;
}

5. Области нажатия кажутся неотзывчивыми или срабатывают на неправильном элементе

Симптом: Кнопки кажутся медленными, или нажатия регистрируются на неправильном элементе — особенно в плотном интерфейсе, таком как меню навигации или списки.

Почему это происходит: Слишком маленькие области касания создают неоднозначность при определении попадания. Современные браузеры обрабатывают события нажатия без исторической задержки в 300 мс (при условии правильного meta-тега viewport), но слишком маленькие области всё равно приводят к промахам или ошибочным нажатиям.

Решение: Стремитесь к областям касания около рекомендации WCAG по размеру цели примерно 44×44 CSS-пикселя. Используйте padding, а не margin, чтобы расширить область нажатия без влияния на макет.

.nav-link {
  min-height: 44px;
  min-width: 44px;
  display: flex;
  align-items: center;
  padding: 0 12px;
}

Заключение

Эти мелкие проблемы мобильного веба редко появляются изолированно — макет, который обрезается, кнопка, которая скрывается, форма, которая увеличивает масштаб. Каждая из них незначительна сама по себе, но вместе они сигнализируют о сайте, который на самом деле не тестировался на устройстве. Современный CSS даёт вам чистые, основанные на стандартах инструменты для решения всех этих проблем. Примените эти исправления один раз, и они будут работать по мере развития браузеров.

Часто задаваемые вопросы

Да. Единицы малого, большого и динамического viewport (svh, lvh, dvh) поддерживаются во всех современных браузерах, включая Safari на iOS 15.4 и более поздних версиях, Chrome, Edge и Firefox. Для старых браузеров вы можете предоставить fallback, объявив height: 100vh перед правилом svh или dvh. Браузер проигнорирует единицу, которую не распознаёт, и использует fallback.

Да, начиная с Safari 16. В более старых версиях iOS Safari overscroll-behavior не имеет эффекта, и цепочка прокрутки всё равно будет происходить. Если вам нужно поддерживать эти старые версии, наиболее надёжным fallback является подход на основе JavaScript, который предотвращает touchmove на body, пока модальное окно открыто.

Отключение масштабирования пользователем убирает возможность увеличения щипком, что является важной функцией доступности для пользователей с плохим зрением. Это также нарушает критерий успеха WCAG 1.4.4. Правильное решение — установить размер шрифта на полях ввода 16px или больше, что предотвращает автоматическое увеличение без ограничения масштабирования для пользователей, которым это нужно.

Только элементы, которые находятся рядом с краями экрана, нуждаются в отступах безопасной зоны. Нижняя фиксированная панель навигации или плавающая кнопка действия рядом с нижним краем выиграют от env(safe-area-inset-bottom). Элементы, позиционированные вдали от краёв экрана или центрированные в viewport, обычно в этом не нуждаются. Всегда тестируйте на устройстве с индикатором Home или вырезом для подтверждения.

Truly understand users experience

See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..

OpenReplay