WEB типографика: размер шрифтов в rem

Опубликовано: Суббота, Июль 27, 2013 Комментарии (11)

Рассуждений про то, какие единицы измерения лучше использовать при задании размера шрифта в верстке, в сети очень много как на русском, так и на английском. Так что здесь я не буду оригинальной и опишу кратко свои поиски лучшей адаптивной (точнее отзывчивой) верстки (в данном случае речь конкретно о шрифтах и т.п.), также сохраню подготовленный мною Compass Framework mixin для конвертирования px в rem.

Отзывчивая верстка: em, rem или % ?

Иногда бывает, что макет нарисован на 1000px и выглядит вполне прилично. Но при верстке, как правило, ограничение на ширину контента больше (в зависимости от макета, конечно, но самые распространенные у меня ограничения 1440px, 1600px). И вот начинается огорчение: тексты смотрятся не на своем месте, отступы кажутся слишком маленькими на большом экране и так далее.

Самое очевидное решение – это сделать типографику тоже гибкой к разрешениям. Но как? Самые распространенные относительные единицы в верстке – это, пожалуй, em, % и rem. Есть еще так называемая Viewport Sized Typography. Но она не работает при ресайзе экрана и вообще в настоящий момент с некоторыми глюками ее поддерживают только самые новые браузеры (IE10+, Firefox 19 +, Safari 6+, Chrome 20+).

Итак, раньше я не знала о существовании rem. em мне казалось не удобно использовать из-за ее слишком “относительной относительности”: значение em зависит от размера родительского элемента. То есть если системный шрифт по умолчанию 16px, то 1em=16px. Но если у body, к примеру, размер 0.875 em (14 px), то у элемента внутри body с размером 1em размер шрифта будет уже 14px. В проекте чуть более среднем по сложности такая система измерений может вызвать массу трудностей и неявной логики.

Так что раньше в верстке я предпочитала комбинировать % и px. Для body font-size и line-height задавала какую-то фиксированную величину в px, которую можно было менять с помощью media queries. А уже для элементов текста задавала font-size и line-height в %. Этот метод я нахожу весьма рабочим, но не всегда удобным.

Относительная единица измерения rem очень похожа на em, но позиционируется она относительно root элемента документа, то есть относительно html. Соответственно, никакой путаницы не может возникнуть и можно переносить все размеры прямо из макета без особо сильных вычислений. При использовании CSS фрэймворка вообще все это можно делать в две строчки: первая в px для старых браузеров, вторая с функцией, вычисляющей rem. Чуть ниже я подробнее напишу про кроссбраузерность при использовании rem (ie8 и ниже не поддерживают rem единицы).

После некоторых колебаний и сомнений  я все же решила переходить на rem.

Применение rem на практике: размеры шрифтов, высота строк, отступы

Как уже сказано мною ранее, rem считается относительно корневого элемента (html). Это очень удобно и просто контролировать весь процесс верстки в целом.

Нужно сначала определить font-size для html:

В данном случае @include screen_…() – это миксы для задания media queries, написанные в Compass Framework.  Пример микса:

После того, как мы задали базовый размер для html, приступаем к работе непосредственно с rem. Во-первых, определимся как переводить px, которые мы видим в макете, в rem. Можно считать где-нибудь в сети (видела калькуляторы px to rem), если вы не используете никаких CSS фрэймворков. Можно написать такой калькулятор самим любыми подручными средствами. В Compass Fr. далеко ходить не нужно, можно просто написать небольшую функцию конвертации px в rem:

Это посчитано по формуле планируемая величина/контекст = результат. Где планируемая величина – это переменная $px, контекст – в нашем случае font-size html = 16 (px).

Прочитать подробнее о вычислении rem и адаптивности.

Теперь можно применять написанную функцию. Для примера задать шрифт для p:

Все эти css правила я сократила до mixin:

Теперь можно записать буквально в одну строчку:

В CSS файле получаем:

Подобным образом можно также задавать отступы в документе, да и в общем-то все, что угодно. Но злоупотреблять, конечно, тоже не стоит. К примеру, если вам требуется задать ширину для блоков, лучше пользоваться процентными соотношениями.

Кроссбраузерный вопрос

1. Если задаешь что-то в rem, нужно не забывать перед этим делать fallback в px (показано в примере выше).
2. Можно использовать js плагин REM unit polyfill. Он определяет, поддерживает ли браузер rem. Если нет, то сканирует стили на наличие rem и все пересчитывает в px. В документации написано, что можно отключать файлы стилей, где не используются rem. У меня этот плагин не заработал и практически повесил ie. Возможно, позже будут более рабочие версии.

Ссылки

Web Typography: Using The Golden Ratio and REM’s
Краткий курс — «Адаптивный сайт за неделю»: типографика и сетка (часть II)
REM unit polyfill

Поделитесь с друзьями:

Читайте также:

Комментируйте:

  • bafxyz

    1) Помоему в mixin ошибка
    $line_h: $font_px * 1; не даст 15px на выходе или я чего-то недопонял.

    2) Ещё можно подробнее узнать про эту запись?
    line-height: (18);
    Зачем в скобках запись?

    3) И к чему запись line-height два раза? Не проще записывать один раз без единиц измерения? Unitless line heights

    В остальном спасибо за статью.

    • Positivecrash

      Добрый день! Спасибо, что заметили ошибки и в целом за внимание.)

      1) Это порезалось скриптом, который отображает код на сайте :) Уже поправила, запись должна быть вида:
      $line_h: $font_px * 1.2;
      В принципе, это я выбрала коэффициент 1.2, как самый адекватный, на мой взгляд, для соотношения размера шрифта с высотой строки. У вас он может быть другим.

      2) Тут тоже как-то закралась опечатка:
      line-height: px-to-rem(18);
      Соответственно, здесь мы используем написанную выше функцию @function px-to-rem($px).

      3)Два раза пишем line-height, потому что первая запись в px, вторая – в rem. Это нужно для поддержки ie < 8, который не понимает rem. То есть, если вы не подключали скрипт для кроссбраузерной поддержки rem, то это просто необходимо.

  • Руслан

    А если шрифты должны менять свой размер не пропорционально относительно друг друга?

    • http://positivecrash.com/ Настя Бакай

      Я так понимаю, вы имели в виду, ситуацию, когда в верстке несколько шрифтов? В случае с rem шрифты изменяются относительно html и никак друг на друга не влияют. Если в макете есть несколько различных шрифтов, то просто указываем для них размеры, которые указаны в макете.

      P.S. кстати, бывает, что макет “резинового” сайта нарисован только на 1000px. В таком случае как раз очень удобно использовать rem в единицах измерения. Берете ширину макета (например, 1000px) и для html = 1000px делаете font-size:100%. Затем проставляете всем шрифтам значения из макета с использованием миксинов, написанных выше (можно и без них обойтись, простым CSS). И далее, как выше в посте, делаете изменения шрифта при меньшей/большей ширине окна с помощью варьирования значения font-size для html.

  • Сергей Артёмов

    С “Viewport Sized Typography“ даже не в поддержке дело (сейчас, когда 3 года прошло с публикации этой статьи, она уже нормальная), и не в работе при ресайзе (как раз это-то работает). Проблема на самом деле в том, что в типографике нельзя просто задавать размеры в процентах (а vw и vh — и есть проценты). Шрифт не должен изменяться в зависимости от размеров окна/экрана. Если только этот размер задавать калком и в этот калк какое-то сложное вычисление забивать. Потому что в том же примере из статьи на css-tricks стоит только сделать вьюпорт например 320px — и читать становится невозможно даже на макбук-ретина (то есть в действительности 640px), уж не говоря о старых смартфонах с низким ppi, где каждая буква, дай бог чтоб за пределы квадратика 2*2px выsлезла.
    Размер шрифта должен базироваться на расстоянии от глаз до экрана. Это сложно знать наверняка, но вьюпорты слегка диктуют эти размеры (заставляют пользователя на подсознательном уровне). Потому что мобильники (даже лопатофоны) люди держат чуть ближе к глазам, чем планшеты, экран ноутбука, чуть дальше чем планшеты, мониторы ещё дальше. С телевизорами всё сложно в этом плане, но спасает сверх низкий ppi. Наверно путанно, но веду я всё к тому, что шрифт должен довольно незначительно изменяться от ширины вьюпорта. Например если на десктопном мониторе основной размер шрифта 20px, то на планшете не факт что вообще должен измениться (он сам собой уменьшится из-за большей плотности пикселей), но для лопатофонов это уже многовато будет и подойдёт наверно 16px, а для обычных мобил — 14, ну минимум 12. Это на ширине допустим 480, тогда как изначальный вариант в 20px — на ширине стандартного монитора (а то и большего).
    Да зависимость есть, но совсем не пропорциональная. Вот почему для шрифтовых и около-шрифтовых (отступы, например) лучше пользоваться rem меняя медиа-запросами слегка только :root {font-size: __px;}. А vh и vw подходят разве что для построение сеток

    • http://positivecrash.com/ Настя Бакай

      “Размер шрифта должен базироваться на расстоянии от глаз до экрана”
      вот это очень хорошая мысль))) но, к сожалению, мы этого не можем контролировать, только догадываться.

      Да, именно этим я и пользуюсь пока: rem + медиа запросы, и размеры не меняю для каждого из устройств. Но правда я, как правило, по-другому делаю: мобилки обычные (начинается обычно от 14 px) -> мобилки большие + планшеты (иногда остается такое же как и на обычных мобилках, зависит еще от читаемости самой гарнитуры) -> десктоп свыше 1024px -> десктоп свыше 1440px -> мониторы свыше 1920 px (но тут я сомневаюсь вообще очень сильно, надо пересматривать свои взгляды уже).

      Пыталась освоить vh и vw интересная идея, хотелось бы чтобы все плавно менялось в размере в зависимости от viewport, но на практике ужас.. даже не очень представляю их для построения сеток, не то что уж все остальное выстраивать.

      • Сергей Артёмов

        Я просто воспринимаю vh и vw как rem для блочных (не шрифтовых) размеров, и то не часто (в смысле только при надобности). Как rem ссылается на html (вместо родителя), так vh и vw ссылаются на размеры вьюпорта (в процентах), а не на размеры родителя.

    • http://positivecrash.com/ Настя Бакай

      вот на счет удаленности глаз от экрана. Недавно как раз размышляла как лучше рисовать один дизайн.. К примеру, есть монитор диагональ 27, 1920px на 1080px. По идее поверхность большая и мой дизайнерский мозг хочет ее максимально полезно использовать. Но на практике (наблюдала за свои мужем) что происходит? Человек утыкается в этот монитор так, что ему бы и сайта в 1000px было бы предостаточно, а все что чуть больше – уже некомфортно О_о Как с этим быть я пока не представляю, если честно

      • Сергей Артёмов

        Вот и я заметил, что без разницы какого размера монитор, хоть 15дюймов, хоть 27. На него пользователи сморят (по крайней мере читая тексты) всегда с одного и того же расстояния примерно (каждый пользователь со своего, удобного ему лично, но всё-таки фиксированного). С мобилами та же ситуация, но расстояние чуть меньше. И тут ещё сложнее в плане пикселей: реальные размеры не сильно отличаются, а ppi — в разы. При этом реальный размер шрифта (например в мм, или дюймах) должен оставаться на них всех одинаковым, тогда только будет комфортно читать. Но с этим реальным размеров всё печально. Самое правильное было бы взять и использовать пункты (1pt=1/72inch). Но вместо этого корпорации всё испортили введением идиотских независимых пикселей, тем что на их основе скалирование врубили в операционнках. В итоге если я задам размер в 72pt например какому-то блоку, его ширина не будет 1 дюйм на моём макбуке (хоть в макоси хоть в винде).
        А то, что “чуть-чуть больше — уже некомфортно”, как я понял это контейнер чуть больше. Для комфортного чтения ширина текстового блока тоже не должна превышать определённую величину. Если экран сильно большой, лучше на колонки текст разбивать, как программные электронные читалки (iBook, GooglePlay-Книги) имитируют книжный разворот.
        В общем типографика на экранах нынешних — та ещё боль. Часами и днями можно рассуждать и сетовать.

        • http://positivecrash.com/ Настя Бакай

          да, все сложно )))
          пыталась ввести текст колонками, с версткой были какие-то проблемы неприятные (уже не помню что именно)
          кстати, SketchApp вроде настаивает на pt

          • Сергей Артёмов

            А я теперь не знаю как pt использовать, когда эппл взяли и свой независимый пиксель обозвали point и сокращённо pt (у гугла — dp). При этом это вовсе не адобовский пункт (про типографский уже и смысле нет говорить), это всё тот же абстрактный пиксель, полунезависимый от density.
            Я периодически пытаюсь попробовать пункты использовать. Но пока ни разу не было удовлетворительных результатов.