Полностью отзывчивый дизайн — это больше, чем просто медиа-запросы

Автор оригинала: Promise Tochi
  • Перевод
  • Tutorial


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


Перевод


Целью данной статьи является получение значения размера шрифта, которое плавно переходит от 14px при ширине окна браузера 769px до 20px для ширины окна браузера 2048px.


Прежде всего, давайте разберемся с определением адаптивного элемента DOM. Адаптивные элементы должны отвечать изменениям размера области просмотра (viewport size). То есть, когда я уменьшаю или увеличиваю размер окна, адаптивный DOM-элемент должен отвечать на эти изменения четко определенным образом.


С помощью медиа-запросов CSS3 мы можем отвечать изменениям экрана в самом CSS. Большую часть времени это брейкпойнты (breakpoints) 480px, 768px и 769px. Они подходят для большинства веб-приложений. Но что, если мы сможем пойти дальше 3, 4, 5 брейкпойнтов? Что если мы сможем отвечать на каждое изменение в 1px окна браузера начиная от 2048px и заканчивая 1px. Это значит, что мы можем создать объявления в CSS, которые отвечают на мои изменения окна браузера с 2048px до 2047px, тем самым отвечая на каждое изменение в 1px до значения в 0px.


Благодаря функции calc в CSS3 и единиц измерения области просмотра (vh, vw) мы можем добиться такой функциональности.


Функция calc позволяет вам производить вычисления значений CSS свойств.


Единицы измерения области просмотра представлены, как проценты от видимой части веб-страницы. Это все окно браузера минус адресная строка, полоса прокрутки, вкладки и так далее.


К счастью, calc и единицы измерения области просмотра поддерживаются вплоть до IE9.


html {
  font-size: 1vh;
}

В примере выше, если ширина браузера минус полоса прокрутки будет 1800px, размер шрифта будет равен 18px, то есть 1% от 1800. С этим все окей, но на экране в 800px размер шрифта будет равен 8px. Это не то, чего мы хотим.


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


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


Прим. переводчика: в оригинальной статье в этом месте содержится некоторая неточность, которая исправлена при переводе.
Так же поправлена неточность с диапазоном (спасибо FreelancerLifeStyle).

(Math.random() * (2048 - 769) + 769)

Это отрывок Javascript кода и все, что он делает — это возвращает число в диапазоне от 769 до 2048. Math.random() генерирует случайное число между 0 и 0.9999999999999999. Мы берем это число и умножаем на разницу между 2048 и 769, которая равна 1279. Это гарантирует, что случайное число * 1279+769, всегда вернет значение между 769 и 2048. Вы можете попробовать это самостоятельно, 0*(1279)+769 равно 769 и 0.999999999999*(1279)+769 возвращает 2047.999999998721.


Теперь у нас есть базис для наших дальнейших вычислений.


В нашем случае мы хотим, чтобы размер шрифта был в диапазоне от 14px до 20px, то есть размер диапазона равен 10px и наша база равна 14px. Мы хотим генерировать случайное число между 0 и 0.999999999999, умножить его на 10 и прибавить к нему 14. Так что, 0*10+14 равно 14 и 0.9999*10+14 равно 23,9999, но у нас нет доступа к Javascript Math.random внутри нашего CSS. Как же в таком случае сгенерировать случайное число, которое нам нужно?


Давайте посмотрим на то, что у нас есть. С помощью единицы измерения VW, мы можем динамически получать ширину окна с помощью 100vw. Выходит, что 100vw на экране 1366px равно 1366px, на экране 1560px равно 1560px, без необходимости жестко записывать в коде значение в пикселях.


С нашим целевым минимальным значение ширины (769px), максимальным значением ширины (2048px) и динамически вычисляемым значением ширины (100vw), мы вооружены тем, что нам нужно для генерации случайного. Просто вычисляя (100vw — 769px)/2048px мы можем генерировать любое значение от 0 и выше, в зависимости от значения 100vw. Так, если ширина области просмотра пользователя будет 1800px, (100vw — 769px)/2048px вычисляется как (1800px — 769px)/2048px в браузере и равно 0.50341796875. У нас есть наше случайное число. Теперь мы можем умножить 0.50341796875 на 10 (помните наш диапазон?), что в результате будет 5.0341796875. Финальным шагом будет прибавить к 5.0341796875 14px, что в результате будет 19.0341796875px, как размер шрифта для пользователя с шириной области просмотра в 1800px. Верхней границей нашего диапазона будет 14px + 10 * ((2048 — 769px) / 2048 и примерно равно 20px.


Финальная формула может быть записана, как:


html {
  font-size: minimumPixel + range * ((viewportWidth - minScreenWidth) / maxScreenWidth)
}

/* Example */

html {
  font-size: calc(14px + 10 * ((100vw - 769px) / 2048));
}

Так что вместо того, что бы обслуживать все размеры экранов между 769px и 2048px одним и тем же размером шрифта (обычно 18px), мы можем динамически обслуживать пользователей с помощью более подходящего диапазона с 14px до 20px.


Это может быть скомбинировано с медиа-запросами, что бы достичь максимально возможной адаптивности.


/* Example */

/* Mobile and Tablet */
@media (max-width: 768px) { 
  html {
    font-size: calc(16px + 2 * ((100vw - 360px) / 768));
  }
}

/* Laptop and Desktops screens */
@media (min-width: 769px) and (max-width: 2048px) {
  html {
    font-size: calc(14px + 10 * ((100vw - 769px) / 2048));
  }
}

/* Excessively large screens */
html {
  font-size: 36px;
}

Это может быть применено не только к размеру шрифта, но и к паддингам, марджинам и размерам ширины, которые будут растягиваться и сжиматься вместе с изменением ширины области просмотра в большую или меньшую сторону.


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


Прим. переводчика:


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


Следующая статья: TV first, отзывчивая типографика или как не забыть о всех размерах девайсов

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 37

    +11

    Пожалуйста, не надо на маленьких экранах уменьшать шрифты. Пользователь ставит в настройках системы тот размер шрифта, который ему комфортно читать. Используйте это значение. И наоборот, не надо вываливать на больших экранах гигантские буквы — их так же не комфортно читать. Вообще, размер шрифта должен зависеть от размера экрана примерно никак.

      0

      Все таки я не соглашусь с тем, что размер шрифта зависит от размера экрана примерно никак. Отображать один и тот же размер шрифта на экране iphone 5 и на экране широкоформатного телевизора вряд ли уместно. Если я, конечно, правильно понял о чем Вы.


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

        +3

        Вы не теоретизируйте, а проверьте как показывается один и тот же "размер" шрифта на разных девайсах. Везде разные "css пиксели".

          0

          Не очень понимаю, что значит "не теоретизируйте" в данном контексте. И как утверждение: "везде разные "css пиксели"" связано с тем, что пользователю с экраном iphone 5 и широкоформатного телевизора нужно показывать один шрифт. Если Вы клоните к тому, что на телевизоре 4K размер шрифта 14px будет выглядеть так же, как и на iphone 5 (из-за разного размера этих пикселей) и давать одинаковый UX, то из исходя чисто из практики это далеко не так.

            0

            Именно к этому и клоню. Если на каком-то телевизоре размер css-пикселей не является удобочитаемым, то это проблема конкретной модели и у неё эти проблемы на всех сайтах.

              0

              То есть Вы всегда используете один размер шрифта на все размеры экрана?

                0

                Агась.

                  0

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

              0
              На мониторах c плотными пикселями браузеры сами множат на 2 все размеры с пикселями если я правильно помню. Иначе навернулись бы все продукты что были до этих мониторов.
            +1
            для удобства пользователя есть чудесная настройка font-size. Используя rem'ы (или em'ы), мы привязываемся к этой настройке. Используя вашу технику, мы игнорируем пользователя, который хотел сделать свой шрифт больше/меньше.
              0

              Правильно ли я понял, что имеется ввиду настройка (например) в настольной версии гугл хром: Внешний вид -> размер шрифта? Если да, то к сожалению ее игнорирует хабр, на котором мы сейчас находимся. Или допустим возьмем такой сайт, как google. Попробуйте поставить очень крупный шрифт в настройках и перейти на google.com. На основной странице вы увидите увеличенные буквы, но как только вы наберете что-то в поиске и нажмете enter, страница с выдачей окажется игнорирующей эту настройку. Если пойти еще дальше и перейти в Настроить шрифты -> Размер шрифта и там выставить максимальные 72, то страница с выдачей поведет себя еще интересней. Сами шрифты проигнорируют эту настройку, а вот все расстояния на странице будут сильно увеличены.


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

                0
                Правильно
            +1
            Пользователь ставит в настройках системы тот размер шрифта, который ему комфортно читать. Используйте это значение.
            Это как?
            Как я понимаю в размер по умолчанию для html устанавливаю браузеры. Практически 16px. Оставляем этот размер для всех устройств? Если у юзера на телефоне выбран очень большой шрифт — то браузер телефона будет показывать те-же 16px или увеличит его? Из браузера мы же не имеем доступа к настройкам размера шрифта телефона — а как тогда «использовать это значение»?

            Вообще, размер шрифта должен зависеть от размера экрана примерно никак.

            Для базового размера шрифта это понятно. А вот для заголовков я бы хотел на больших экранах заголовки побольше. Например для больших экранов h1- 4rem, будет вполне нормально выглядеть, но на телефоне такой заголовок будет слишком.
              –1
              Из браузера мы же не имеем доступа к настройкам размера шрифта телефона — а как тогда «использовать это значение»?

              font-size: 1rem

              для больших экранов h1- 4rem, будет вполне нормально выглядеть

              Не будет.

                0

                Но какое это имеет отношение к системным настройкам шрифта в системе пользователя? Возьмём к примеру IOS и системные настройки Text Size. Изменение системного Text Size в любую сторону никак не влияет на размеры шрифтов на веб-страницах в браузерах IOS.

                  0

                  Поищите соответствующий пункт в настройках браузера.

                    0

                    Настройки браузера != настройки системы пользователя. Вы говорили о том, что нужно брать именно настройки системы. Комментарий Almatyn, как я понимаю, был именно об этом.

                      +1

                      В настройках Firefox под Android есть пункт "Использовать системный размер шрифта".

                        0

                        IOS в данный момент не предоставляет такой возможности пользователю. Настройки отображения браузера и настройки шрифтов в системе регулируются отдельно.

              +1
              Не соглашусь.
              Конечно же размер шрифта зависит от экрана. Обе эти сущности основаны на занимаемой площади и контрасте. На большом экране количества информации больше, поэтому заголовки приходится выделять сильнее, чтобы выделять структуру документа. На мобиле это практически не требуется.
              Поэтому решения по адаптивности размера и отступов очень и очень хороши. www.npmjs.com/package/rfs

              Тут на хабре h1 32px. В мобильной 22px. Ужасно было бы сделать везде h1 заголовки 22px. Это технически абсолютно приемлиемо, но убежден, что статиситически в любом слепом тесте больший размер шрифта на десктопах будет восприниматься как более одобряемый. Так сделано, наверное, в 90% всех популярных сайтов.

                0

                В мобильной 24px, а в ленте на десктопе 28px. И эту разницу вы на глаз не заметите. А вот что вы заметите, так это то, что заголовок из 3 слов не влезает по ширине и начинает переноситься.

                  +1
                  у меня 20px на мобиле в ленте (пресет iphone 6/7/8)и 28px на десктопе. Но не суть. Разницу в 4px очень не сложно заменить,
                  image
                  а при 8 еще сильнее.
                  Если говорить о словах, то о каких именно, если о «сказ о css» то и при 40px не перенесется. А если о «сложности синтеза тетрагидропиранилциклопентилтетрагидропиридопиридина» то никуда не влезет.
                  Влезет или нет это отдельная история. Не думаю, что есть некий универсальный размер куда прям явно можно попасть, чтобы не было висячих строк и смотрелось норм. обычно чуть крупнее основного на мобиле, а то и вообще можно обойтись одним strong иногда, а на десктопе эта минимальная разница не так важна и может быть увеличина 2-4 раза. Накупят себе 32 мониторов. У них там все заголовки как чешуйницы в туалете. Все от идеи.
                0
                Согласен. Дико раздражает что некоторые сайты на большом мониторе используют гигантские заголовки отступы и шрифты… Это как читать книгу где шрифт меняется от размера страницы…
                0
                А что если пользователь увеличивает экран? Вёрстка не начинает ехать?
                  0

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

                    0
                    А это как сверстать. Гармоничные отступы конечно уедут, но на флексах положения блоков должны оставаться в предполагаемой схеме обычной адаптивности.
                    0

                    а % нам зачем?

                      0
                      Наверное, это самая сложноконтролируемая единица. Ну ее нафиг.
                      0
                      Если не брать во внимание слабую браузерную поддержку, почему бы не использовать что-то типа такого:
                      h1 {
                         font-size: clamp(.7cm, 5vw, 1.5cm);
                      }
                        0
                        Потому что размер шрифта не может зависеть от вьюпорта прямо пропорционально.
                        Во-первых, это бессмысленно.
                        Во-вторых, ломает браузерное масштабирование.
                          0
                          1. Отсутствие аргументации. Субъективно.
                          2. Проверено в ff и хроме — прекрасно масштабируется и ничего не ломается.
                            0
                            1. Когда человек покупает большой монитор, он хочет, чтобы в экран помещалось больше контента, а не столько же как и раньше, но крупнее. Поэтому увеличивать шрифт на большом мониторе можно, но не прямо пропорционально.
                            2. Плохо проверяете. Если указать размер шрифта в единицах vw, то он перестаёт реагировать на масштабирование. Совершенно понятно почему: при увеличении масштаба виртуальный размер вьюпорта уменьшается в такое же количество раз, во сколько увеличивается размер css-пикселя. Одно сокращается на другое, получается тот же самый размер в физических пикселях.
                              0
                              Суть моего предложения — в привязке к зрению в реальности, вне зависимости от размера монитора. Хотя наверно вы правы на счет проблемы с масштабированием, однако и неправы одновременно, потому что игнорируете работу функции clamp().
                        0

                        В точке 2048px шрифт примерно 20px, а должен быть 24px. Или я что-то не верно понял?

                          0

                          Да, конечно. Вы правы. Это я не поправил в переводе, хотя нужно было. Диапазон будет до 20px. Еще одна ошибка автора оригинальной статьи. Исправлю, спасибо!

                          0
                          Я тут взялся и сделал рабочий вариант! habr.com/ru/post/501392
                            0
                            интересная статья, отличный перевод!

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

                            Самое читаемое