Все мобильные браузеры имеют два окна просмотра. Область просмотра макета ограничивает ваш CSS - width: 100% означает 100% области просмотра макета, в то время как визуальное окно просмотра описывает область страницы, которую в данный момент видит пользователь. Эта визуализация двух окон просмотра может быть полезна в качестве напоминания.

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

Приветствуются некоторые изменения области просмотра, такие как изменение размера визуального окна просмотра после изменения ориентации или действия масштабирования. Другие эзотерические, например, переписывание метатега области просмотра. Третьи рассматриваются как раздражение, особенно появление и исчезновение панелей инструментов браузера и программной клавиатуры.

Событие изменения размера

Событие resize должно срабатывать всякий раз, когда изменяется размер любого из двух окон просмотра, и на рабочем столе оно делает именно это - в основном потому, что оба окна просмотра равны окну браузера, а изменение размера окна браузера запускало это событие со времен Netscape 3.

На мобильных все сложнее. Брауни указывает на вас, если вам в голову приходит термин «зависимый от браузера»: вы достигли уровня паранойи, соответствующего фундаментальным исследованиям браузеров. Добро пожаловать в мой мир.

Событие изменения размера довольно надежно, когда происходит изменение ориентации или когда панель инструментов браузера входит или покидает экран. В других ситуациях не так уж и много.

Что общего между изменениями ориентации и панелями инструментов? Я понятия не имею. Для меня загадка, почему именно эти два варианта использования должны быть надежными, а другие, возможно, более важные, - нет.

Вы знаете, к чему все это идет, верно? Итак, вот вам: неизбежная таблица совместимости для вашего удовольствия. Не придавайте слишком большого значения логике; различия браузеров не совсем логичны. Позже в этой статье мы рассмотрим несколько наиболее важных из них.

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

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

Общие изменения визуального окна просмотра

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

Все браузеры запускают событие изменения размера, когда пользователь меняет ориентацию. (Для тех из вас, кто любит ломать голову, подумайте, что происходит, когда пользователь меняет ориентацию на 180 градусов. Является ли это изменением ориентации? Или изменением размера?)

Однако только Edge, BlackBerry 10 и Android WebKit WebViews (но не обычные браузеры) запускают событие изменения размера, когда пользователь увеличивает масштаб. Таким образом, в большинстве браузеров невозможно определить, когда пользователь увеличил масштаб - ну, вы можете запустить скрипт, который время от времени проверяет размер визуального окна просмотра, но снижение производительности будет ... давайте не будем туда идти, хорошо?

В некоторых ситуациях важно знать, когда пользователь выполняет масштабирование, особенно когда вы используете position: fixed и беспокоитесь, что пользователь может не увидеть весь фиксированный элемент. (Теоретическое решение здесь - позиция: фиксировано устройством, но пока оно реализовано только в Edge.)

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

Изменение мета вьюпорта

Можно «на лету» переписать метатег области просмотра и заставить браузеры изменять размер области просмотра макета. (Однако полностью удалить тег невозможно.) Вот так - и да, это работает во всех браузерах:

var metaViewport = document.querySelector('meta[name=viewport]');
metaViewport.setAttribute('width','380');

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

Это изменение размера области просмотра макета вызывает событие изменения размера, за исключением Safari / iOS. Таким образом, браузеры правильно обрабатывают этот непонятный крайний случай, чего бы он ни стоил.

Панели инструментов и клавиатуры

Теперь мы переходим к сути: входящие и исходящие панели инструментов и клавиатуры. Типичная панель инструментов браузера, которая содержит строку URL и, возможно, кнопки «Назад» или «Обновить», занимает около 60 пикселей по вертикали. Это пространство не является частью окна браузера, поэтому высота визуального окна просмотра на 60 пикселей меньше, чем можно было бы предположить.

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

Например, как недавно заметил Джереми, vh юнитов, которые теоретически имеют большой смысл в адаптивном дизайне, дают осечку из-за этого изменения визуального окна просмотра. Если вы укажете элемент height: 100vh (т.е. 100% высоты визуального окна просмотра), он изначально работает отлично, но как только пользователь прокручивает высоту визуального окна просмотра, высота увеличивается примерно на 60 пикселей, и элемент также становится на 60 пикселей выше, что может привести к поломке страницы. макет.

Джереми также отмечает, что эту проблему невозможно решить только с помощью CSS. Вы можете использовать JavaScript, как мы вскоре увидим, но это может замедлить ваши страницы. Поэтому решение должно исходить от самих производителей браузеров.

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

Это круто, но, возможно, сейчас это не поможет вам и не применимо ни к одному другому браузеру, кроме последней версии Google Chrome. Тем не менее, это лучшее решение, и я боюсь, что нет другого выбора, кроме как проявить немного больше терпения.

Клавиатуры в Safari / iOS

Вдобавок у iOS (сюрприз!) Есть своя уникальная проблема. В то время как во всех других браузерах добавление программной клавиатуры ограничивает окно браузера и, следовательно, визуальное окно просмотра, в iOS программная клавиатура является независимым слоем, который отображается в верхней части окна браузера. Окно браузера никак не реагирует на появление или исчезновение клавиатуры. Визуальное окно просмотра не изменяется, и событие изменения размера не запускается.

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

Заключение

Таким образом, мы остаемся с удручающе неполной картиной. Изменение размера области просмотра работает большую часть времени, причем проблема с клавиатурой Safari является наиболее важным исключением, но текущих событий JavaScript недостаточно для отслеживания всех изменений. В частности, нам нужно событие масштабирования.

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