Введение

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

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

Проблема

При указании свойства min-width: 320px для тега body в Firefox, контент, при достижении минимальной ширины, не начинает пропорционально уменьшаться как в Chrome (рис 1), а просто выходит за экран. (рис 2)

 Рисунок. 1 
Демонстрация правильной работы min-width: 320 для body в Chrome 105
(После 320px начинает пропорционально уменьшаться)
Рисунок. 1 Демонстрация правильной работы min-width: 320 для body в Chrome 105 (После 320px начинает пропорционально уменьшаться)
Рисунок. 2
 Демонстрация неправильной работы min-width: 320px для body в Firefox 103 (После 320px появляется горизонтальный скролл)
Рисунок. 2 Демонстрация неправильной работы min-width: 320px для body в Firefox 103 (После 320px появляется горизонтальный скролл)

Зачем решать эту проблему?

Допустим, у меня сломался основной смартфон, а в запасе только 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 появляется горизонтальный скролл)

В принципе, свойство 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() не меняя размеры (Контент выглядит хорошо, но скролл остается)

Да, для масштабирования с изменением размера существует 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 с созданной функцией (Контент масштабируется, скролла нет)

О том как использовать функцию

Для начала, зайдите на репозиторий 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)


  1. anonymous
    06.09.2022 18:09

    НЛО прилетело и опубликовало эту надпись здесь


    1. naff
      06.09.2022 18:39
      +1

      Что за нелепый самопиар с mol?


      1. anonymous
        06.09.2022 22:57

        НЛО прилетело и опубликовало эту надпись здесь


        1. naff
          07.09.2022 07:17
          -2

          Я где то писал что жду от вас чего то? У вас проблемы с чтением


    1. Layan
      07.09.2022 01:22
      +2

      Это по вашему хорошая адаптивность?

      Ничего не прочитать при изменении размера окна


  1. md_backend_binance
    06.09.2022 21:46

    помню когда я первый раз сделал горизонтальный скрол и узнал что его можно крутить только с зажатой shift это был шок )

    в 2022 еще не добавили нормальной адаптации из коробки или все так применяют хаки с разворотами?


    1. webfrontden Автор
      07.09.2022 07:30

      Да, универсальной пилюли, чтобы стало хорошо, пока нет (а может никогда и не будет). Но на самом деле, все не так плохо. Постоянная доработка Flex и Grid, новые свойства вроде clamp, min и max, сильно упрощают жизнь разработчика.
      Если посмотреть со стороны, мы движемся в прекрасный мир адаптива без мороки, где нам доступно все больше и больше инструментов. Хотя как и везде, повозка движется, но движется медленно, т.к все тянут её в разные стороны, кто-то вводит то, кто-то это. Те же самые Mozilla ввели поддержку gap для Flexbox на два года раньше Chrome, но не могут исправить работу min-width для body.
      И именно поэтому, пока ждём что-то хорошее и универсальное, но даже когда такое появится, использовать не будем, а будем снова ждать, года два, пока все начнут поддерживать это.


  1. Quilly
    07.09.2022 04:16

    Что-то не совсем понял, а зачем вообще на теге body устанавливать min-width? Почему у меня сайт спокойно ресайзится вплоть до +-180px без всяких скроллбаров? Вешать обработчик на resize event и без debounce? Нет. Спасибо. Сами создали проблему. Сами же ее решили. Молодцы.


    1. webfrontden Автор
      07.09.2022 04:40

      Устанавливать min-width для body или нет зависит от того, хорошо ли адаптируется контент на сайте или нет. Если на сайте за viewport выходят правильно адаптированные изображения, они и до 60px будут резиниться, а если за экран выходит заголовок с размером шрифта в 50px, максимум, что может сделать браузер, это перенести слова на новую строчку, а если слово большое, разрывать его не разрешено, оно просто выйдет за viewport и создаст горизонтальный скролл.

      Да, безусловно, с помощью медиазапросов можно и тот же самый текст адаптировать, изменяя его размер, вплоть до устройств с шириной экрана в 100px, но тут уже вопрос рациональности. Зачем вручную оптимизировать сайт под очень редко используемые устройства (ширина большинства смартфонов более чем 320px), если можно больше времени уделить хорошему адаптиву для смартфонов в 320px, а затем указать min-width для body и использовать функцию, которая в итоге справится не хуже, а время сэкономит.

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


      1. wadowad
        07.09.2022 13:06
        +1

        Вариант решения проблемы с крупными заголовками:

        h1 {
          font-size: 40px;
          font-size: clamp(1.1em, 8vw, 2.7em);
        }


  1. delphinpro
    07.09.2022 08:22
    +2

    Как-то слишком заморочено.
    Зачем делать ручное масштабирование, если это можно отдать на откуп браузеру?
    Мобильные браузеры ориентируются на meta viewport, это и используем.

    В крайне редких случаях, когда приходится фиксировать минимальную ширину body я просто корректирую javascript-ом вышеназванный тег viewport
    gist.github.com/delphinpro/a962978d668b63e046889efd1073a67c
    В примере min-width: 640px
    Код помещается в шапку страницы и отрабатывает один раз. Учитывая, что в мобильном устройстве изменить размер окна (почти) нельзя, это норм.
    Хотя, если нужно учесть поворот в альбомный просмотр, то можно обернуть в слушателя matchMedia.

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


  1. krylov_sn
    07.09.2022 11:07

    Если честно я не очень понимаю, почему браузер должен дополнительно что-то масштабировать. В свойстве указано - минимальная ширина такая-то. Это значит, что разработчик сайта принял такое решение. Таким он видит свой сайт - почему браузер должен что-то дополнительно делать? Если некомфортно что-то просматривать - есть режим для чтения. Тут уже браузер и пользователь решают как они хотят читать контент.

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