EM vs REM vs PX – почему вы не должны использовать только пиксели

Дебатов было много, так какие единицы измерения нужно использовать в CSS?

Много разработчиков были готовы закопать REM и вернуться к любимым пикселям. Мы забыли, почему приняли решение использовать REM в первую очередь. Проблема не только вращаются вокруг размера шрифта - это еще и доступность.

  • Пиксели игнорируем и не используем.
  • Используйте REM для размеров и расстояния.
  • Используйте EM для медиа запросов.

Пиксели

Пиксели (px) это то, к чему мы все привыкли за эти годы. Каждый знает, что такое пиксель (хотя размер пикселя не всегда то же самое). Все удобно с помощью пикселей. Они легко переводимы. Дизайнеры, как правило, работают в пикселях, так легко взять размеры напрямую из Photoshop прямо в проект.

Так что с пикселями?

Доступность

Я большой сторонник доступности в вебе. Я бы взял доступность над "довольно" в любой день.

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

В большинстве браузеров, пользователь может установить по умолчанию свой размер шрифта, чтобы быть разного размера по умолчанию (обычно 16px). Если пользователь устанавливает их по умолчанию в 20px, все размеры шрифта должны масштабировать соответственно.

Тем не менее, если сайт явно устанавливает размеры шрифта в пикселях, заголовок устанавливается в 30px всегда будет 30px. Это может звучать отлично от дизайнера или разработчика - но вы не пользователи, прекратите делать сайты для себя.

К счастью, установка размера шрифта в пикселях полностью не разрушит доступности. Пользователь может увеличивать и уменьшать масштаб с помощью Ctrl и +/- . Однако, мы можем сделать лучше.

REM

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

REM показывает размер шрифта корневого элемента (например, размер шрифта для элементов тега <html>). При использовании на размер шрифта на этой корневой элемент, он представляет свое первоначальное значение.

Как рассчитать PX от REM

Основной и наиболее распространенный пример: HTML размер шрифта установлен в 10px, параграф установлен в 1.6rem - 1.6rem * 10px = 16px.

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

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

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

Так как же мы можем не ломать наши доступности?

Установите корневой HTML размер шрифта в процентах. Это процент браузера по умолчанию размера шрифта пользователя. Типичный способ установить HTML размер шрифта до 62,5%. Это потому, что 62,5% 16px (по умолчанию размер шрифта) является 10px. Что бы еще сделать 1.6rem = 16px. Это теперь означает, что если размер шрифта в браузере пользователя по умолчанию меняется на, например, 20 пикселей, 1.6rem будет теперь равна 20px. Так что если пользователь хочет больше шрифтов, пусть. Счастливый дизайнер. Счастливый Разработчик. Все цифры по-прежнему легко работают.

Идеальный сценарий должен был бы оставить HTML размер шрифта как 100%, но это делает математику немного сложнее. Например, 16px теперь 1rem, 20px является 1.25rem, 24px является 1.5rem и т.д.

Спасение с помощью Sass/SCSS

Работать над всеми этими цифры в вашей голове будет уходить довольно много времени. К счастью, если вы используете Sass/SCSS, Less, или любой другой CSS препроцессор, вы не должны беспокоиться. Вы можете использовать функции для расчета этих вещей.

Что насчет EM?

EM первоначально выполняется аналогичным образом как REM, пока он не доходит к вложенности. Например, возьмите DIV с размером шрифта 2em, а затем добавить параграф с размером шрифта 2em. Размер шрифта этого параграфа теперь 2em относительно DIV. Можно быстро потерять след математических расчетов и какой размер есть что, и он быстро становится неуправляемым. Это то, что REM решает - размер всегда относится к корню.

Что насчет медиа-запросы?

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

В этом блоге освещаются некоторые из ключевых различий между использованием пикселей, EM и REM в медиа-запросах https://zellwk.com/blog/media-query-units/.

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

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

Вот некоторые примеры:

Мы используем 6 знаков после запятой, поскольку некоторые браузеры не показывают никакой разницы между 2-5.d.p.

Пример 1: в браузере установлен режим масштабирования 100%, ширина браузера устанавливается на 640pх

min-width: 64em = Hit
max-width: 63.99em = Miss
max-width: 63.999999em = Hit
min-width: 640px = Hit
max-width: 639px = Miss
max-width: 639.999999px = Miss

Пример 1б: в браузере установлен режим масштабирования 100%, ширина браузера устанавливается на 639pх

min-width: 64em = Miss
max-width: 63.99em = Hit
max-width: 63.999999em = Hit
min-width: 640px = Miss
max-width: 639px = Hit
max-width: 639.999999px = Hit

Поэтому мы не можем использовать 6dp для EM, так как она попадает как медиа-запросы.

Пример 2: в браузере установлен режим масштабирования 110%, ширина браузера устанавливается на 704pх (потому что 640px * 110% = 704px)

min-width: 64em = Miss
max-width: 63.99em = Miss
max-width: 63.999999em = Hit
min-width: 640px = Miss
max-width: 639px = Miss
max-width: 639.999999px = Hit

Пример 2б: в браузере установлен режим масштабирования 110%, ширина браузера устанавливается на 705pх

min-width: 64em = Hit
max-width: 63.99em = Miss
max-width: 63.999999em = Miss
min-width: 640px = Hit
max-width: 639px = Miss
max-width: 639.999999px = Miss

Таким образом, мы не можем использовать 2dp для EM. Так что все мы остались на этом этапе является 6dp пикселей. Это работает с зумом браузера. Однако...

Пример 3: в браузере установлен режим масштабирования 100%, размер шрифта браузера 20px, ширина браузера устанавливается на 800pх (потому что 640 * 125% = 800)

min-width: 64em = Hit
max-width: 63.99em = Miss
max-width: 63.999999em = Hit

Так опять же, 6dp EM все еще вне. И мы не можем использовать пиксели длямедиа запросов, потому что они по-прежнему попадают в 640px/639px, потому что они игнорируют EM/REM.

Каково же решение?

К сожалению, нет ответа. Пока браузеры не разберутся с вопросами округления, мы немного застряли.

Самый простой приемлемый вариант, это то, что бы мы никогда не создадим min-width и max-width перекрытия в одном блоке. Пример:

body {
    @media screen and (max-width: 63.99em) {
        background: blue;
    }

    @media screen and (min-width: 64em) {
        background: blue;
    }
}

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

body {
    background: blue;

    @media screen and (min-width: 64em) {
        background: blue;
    }
}

Почему нет реального решения? Я не верю, мало кого волнует. Любая статистика говорит, что люди не меняют в своем браузере по умолчанию размер шрифта, безусловно, перекос. Опции в Chrome, чтобы изменить размер шрифта по умолчанию теперь очень хорошо спрятана в дополнительных опциях браузера.

Подводные камни

Есть некоторые подводные камни этого подхода:

  • Если вы привыкли писать как min-width и max-width медиа запросов в том же блоке кода, это займет больше времени.
  • Увеличивается сложность, как вам придется переопределить CSS одну или другую сторону, а не сообщая браузеру использовать опцию A или B.
  • Увеличивается размер файла из-за этих переопределений. Не намного, но это стоит рассматривать.

В зависимости от проекта, кто его разработчики, а также различные другие факторы, такие как бюджеты проектов (мы должны быть здесь реалистами), использование пикселей может быть проще и быстрее. Также может быть проще и быстрее игнорировать доступность.

Помните, для кого вы создаете веб-сайты.