Введение
Устройства пользователей в наши дни отличаются широким разнообразием: телевизоры, смартфоны, планшеты и даже часы — с каждого из устройств пользователь может захотеть выйти в сеть. А если добавить сюда разные браузеры, которые можно установить на устройство, то получатся тысячи комбинаций того, как можно попасть на ваш сайт.
Вот и я, в ходе работы над своим сайтом портфолио, тестировал его в разных браузерах и наткнулся на проблему.
Проблема
При указании свойства min-width: 320px для тега body в Firefox, контент, при достижении минимальной ширины, не начинает пропорционально уменьшаться как в Chrome (рис 1), а просто выходит за экран. (рис 2)
![Рисунок. 1
Демонстрация правильной работы min-width: 320 для body в Chrome 105
(После 320px начинает пропорционально уменьшаться) Рисунок. 1
Демонстрация правильной работы min-width: 320 для body в Chrome 105
(После 320px начинает пропорционально уменьшаться)](https://habrastorage.org/getpro/habr/upload_files/0fe/529/aca/0fe529aca15fe86824a19d2bffa3e267.gif)
![Рисунок. 2
Демонстрация неправильной работы min-width: 320px для body в Firefox 103 (После 320px появляется горизонтальный скролл) Рисунок. 2
Демонстрация неправильной работы min-width: 320px для body в Firefox 103 (После 320px появляется горизонтальный скролл)](https://habrastorage.org/getpro/habr/upload_files/d52/3f5/b42/d523f5b4225a9bb9710b1e45d184c0df.gif)
Зачем решать эту проблему?
Допустим, у меня сломался основной смартфон, а в запасе только Samsung Galaxy Mini с шириной экрана в 240px и с браузером Firefox. На таких устройствах, треть контента сайта будет выходить за viewport, что приведет к появлению горизонтального скролла, а это не удобно.
Также поддержка ширины в менее чем 320px, может быть полезна для браузеров в которых есть функция боковых веб-панелей (например Vivaldi).
Поддержка min-width для body в других браузерах
В ходе тестирования в других браузерах, оказалось, что Safari (проверялось на Safari 15) также имеет данную проблему. (рис 3)
![Рисунок. 3
Демонстрация работы неправильной работы min-width: 320px для body в Safari 15 (После 320px появляется горизонтальный скролл) Рисунок. 3
Демонстрация работы неправильной работы min-width: 320px для body в Safari 15 (После 320px появляется горизонтальный скролл)](https://habrastorage.org/getpro/habr/upload_files/aa0/868/dfb/aa0868dfb825c689d3ceefd9ccb56ad3.gif)
В принципе, свойство min-width для body без проблем работает на всех браузерах с движком Chromium. По крайней мере, кроме Chrome, все работает как положено в последних версиях Edge (105), Vivaldi (5.4), Opera (90.0.4480) и Yandex (102).
Решение
Сначала, я попробовал решить данную проблему путем добавления свойства min-width, не только к тегу body, но и к тегу html и обертке контента div class="wrapper"
, увы, данный способ не сработал.
В связи с этим, я написал функцию, которая уменьшает контент при достижении определенной ширины экрана. Она сравнивает ширину контента страницы с доступной шириной окна (viewport), а затем уменьшает страницу так, чтобы эти значения оставались равны.
При этом, масштабирование страницы является не только визуальным как в случае с transform: scale(), но и влияет на размеры. Если не влиять на ширину, контент будет выглядеть хорошо, но горизонтальный скролл останется. (рис 4)
![Рисунок. 4
Демонстрация того, что будет происходить в старых версиях Firefox, если использовать transform: scale() не меняя размеры (Контент выглядит хорошо, но скролл остается) Рисунок. 4
Демонстрация того, что будет происходить в старых версиях Firefox, если использовать transform: scale() не меняя размеры (Контент выглядит хорошо, но скролл остается)](https://habrastorage.org/getpro/habr/upload_files/41b/344/ba0/41b344ba077fa20a83bc392469fe188e.gif)
Да, для масштабирования с изменением размера существует CSS свойство zoom, которое не только масштабирует элемент как свойство transform: scale(), но и пропорционально меняет его размеры, влияя на окружение. К сожалению, в Firefox свойство zoom не поддерживается (Can I Use Zoom). И именно поэтому для масштабирования применяется связка свойств transform: scale() и width.
CSS свойства применяются к тегу html, так как на теге body установлено свойство min-width и свойство width не будет работать.
Ниже приведен пример работы функции. (рис 5)
![Рисунок. 5
Демонстрация правильной работы min-width: 320px для body в Firefox с созданной функцией (Контент масштабируется, скролла нет) Рисунок. 5
Демонстрация правильной работы min-width: 320px для body в Firefox с созданной функцией (Контент масштабируется, скролла нет)](https://habrastorage.org/getpro/habr/upload_files/088/abd/430/088abd4303a1e80c6f3ca3efe96a63b1.gif)
О том как использовать функцию
Для начала, зайдите на репозиторий GitHub: https://github.com/fazdendev/adaptive-body-min-width
Затем, скопируйте код из function.js к себе в проект и вызовите функцию.
adaptiveSizePageScaleInit(300)
В качестве аргумента передайте в неё ширину окна браузера, при котором функция должна запускаться (по умолчанию 320). Очень важно, чтобы значение body min-width было равно значению переданному в функцию.
Если вы хотите, чтобы функция запускалась только в определенных браузерах уберите вызов функции adaptiveSizePageScaleInit()
, после чего скопируйте функцию вызова кода в определённых браузерах.
startOnSpecificBrowserInit()
Замените строку "НЕОБХОДИМЫЙБРАУЗЕР" из условия кросс браузерной функции нужным вариантом из списка: "other", "msEdge", "chrEdge", "opera", "сhrome", "ie", "firefox", "safari".
Условие, в котором нужно менять строку:if (browser == "НЕОБХОДИМЫЙБРАУЗЕР") {adaptiveSizePageScaleInit()}
Заключение
Я надеюсь, что эта статья была вам полезна!
В будущем, я добавлю функции возможность брать значение body min-width из CSS, так чтобы вам не пришлось задавать переменную вручную.
Если у вас есть какие вопросы или предложения по решению данной проблемы, я буду рад обратной связи.
Ну а на этом все, хорошего вам дня!)
Комментарии (12)
md_backend_binance
06.09.2022 21:46помню когда я первый раз сделал горизонтальный скрол и узнал что его можно крутить только с зажатой shift это был шок )
в 2022 еще не добавили нормальной адаптации из коробки или все так применяют хаки с разворотами?
webfrontden Автор
07.09.2022 07:30Да, универсальной пилюли, чтобы стало хорошо, пока нет (а может никогда и не будет). Но на самом деле, все не так плохо. Постоянная доработка Flex и Grid, новые свойства вроде clamp, min и max, сильно упрощают жизнь разработчика.
Если посмотреть со стороны, мы движемся в прекрасный мир адаптива без мороки, где нам доступно все больше и больше инструментов. Хотя как и везде, повозка движется, но движется медленно, т.к все тянут её в разные стороны, кто-то вводит то, кто-то это. Те же самые Mozilla ввели поддержку gap для Flexbox на два года раньше Chrome, но не могут исправить работу min-width для body.
И именно поэтому, пока ждём что-то хорошее и универсальное, но даже когда такое появится, использовать не будем, а будем снова ждать, года два, пока все начнут поддерживать это.
Quilly
07.09.2022 04:16Что-то не совсем понял, а зачем вообще на теге body устанавливать min-width? Почему у меня сайт спокойно ресайзится вплоть до +-180px без всяких скроллбаров? Вешать обработчик на resize event и без debounce? Нет. Спасибо. Сами создали проблему. Сами же ее решили. Молодцы.
webfrontden Автор
07.09.2022 04:40Устанавливать min-width для body или нет зависит от того, хорошо ли адаптируется контент на сайте или нет. Если на сайте за viewport выходят правильно адаптированные изображения, они и до 60px будут резиниться, а если за экран выходит заголовок с размером шрифта в 50px, максимум, что может сделать браузер, это перенести слова на новую строчку, а если слово большое, разрывать его не разрешено, оно просто выйдет за viewport и создаст горизонтальный скролл.
Да, безусловно, с помощью медиазапросов можно и тот же самый текст адаптировать, изменяя его размер, вплоть до устройств с шириной экрана в 100px, но тут уже вопрос рациональности. Зачем вручную оптимизировать сайт под очень редко используемые устройства (ширина большинства смартфонов более чем 320px), если можно больше времени уделить хорошему адаптиву для смартфонов в 320px, а затем указать min-width для body и использовать функцию, которая в итоге справится не хуже, а время сэкономит.
P.S. Пожалуйста, скиньте ссылку на сайт про который вы говорите. Уж очень хочется узнать, как там реализован адаптив.
wadowad
07.09.2022 13:06+1Вариант решения проблемы с крупными заголовками:
h1 { font-size: 40px; font-size: clamp(1.1em, 8vw, 2.7em); }
delphinpro
07.09.2022 08:22+2Как-то слишком заморочено.
Зачем делать ручное масштабирование, если это можно отдать на откуп браузеру?
Мобильные браузеры ориентируются на meta viewport, это и используем.
В крайне редких случаях, когда приходится фиксировать минимальную ширину body я просто корректирую javascript-ом вышеназванный тег viewport
gist.github.com/delphinpro/a962978d668b63e046889efd1073a67c
В примере min-width: 640px
Код помещается в шапку страницы и отрабатывает один раз. Учитывая, что в мобильном устройстве изменить размер окна (почти) нельзя, это норм.
Хотя, если нужно учесть поворот в альбомный просмотр, то можно обернуть в слушателя matchMedia.
Возможно, это не будет работать в режиме просмотра devtools, но ведь этого и не требуется. В этом режиме достаточно просматривать на минимальной ширине.
krylov_sn
07.09.2022 11:07Если честно я не очень понимаю, почему браузер должен дополнительно что-то масштабировать. В свойстве указано - минимальная ширина такая-то. Это значит, что разработчик сайта принял такое решение. Таким он видит свой сайт - почему браузер должен что-то дополнительно делать? Если некомфортно что-то просматривать - есть режим для чтения. Тут уже браузер и пользователь решают как они хотят читать контент.
Если дизайнер и разработчик не хотят видеть на своем сайте определенную категорию людей - это их решение и их профессиональные качества. Как раз считаю поведение Chromium браузеров по сути нарушением стандарта, недокументированным поведением
anonymous
НЛО прилетело и опубликовало эту надпись здесь
naff
Что за нелепый самопиар с mol?
anonymous
НЛО прилетело и опубликовало эту надпись здесь
naff
Я где то писал что жду от вас чего то? У вас проблемы с чтением
Layan
Это по вашему хорошая адаптивность?
Ничего не прочитать при изменении размера окна