EM, REM або PX – чому не можна використовувати «тільки пікселі»

2

Від автора: суперечки ведуться вже давно – які одиниці вимірювання використовувати в CSS? Ми, як і багато інших, спочатку перейшли на REM і потім повернулися до улюблених пикселів. Ми просто втратили той слід, чому ми перейшли на REM одиниці. Проблема пов’язана не тільки з розміром шрифту, але і з доступністю.

Якщо коротко:

пікселі – це кам’яний вік, не використовуйте їх;

використовуйте REM для розмірів шрифтів і відступів;

використовуйте EM для медіа-запитів.

Пікселі

За всі ці роки ми звикли до пікселях (px). Всі знають, що таке піксель (хоча розмір пікселя не завжди однаковий, але це тема іншої статті). Всім зручно працювати з пікселями, їх легко переводити. Дизайнери працюють у пікселях, дуже зручно брати розміри прямо з Photoshop і переносити їх у верстку.

Що ж не Так з пікселями?

Доступність

Я великий прихильник доступність в інтернеті.

Якщо ви вказуєте всі шрифти, елементи та відступи в пікселях, ви не поважаєте кінцевого користувача.

В більшості браузерів користувач може змінити розмір шрифту (зазвичай це 16px). Якщо користувач вказав розмір шрифта 20px, всі шрифти повинні збільшитися пропорційно.

Однак якщо на сайті чітко прописаний розмір шрифту в пікселях, то заголовок розміром 30px завжди буде 30px. Від дизайнера/розробника це може звучати круто, але ви не звичайний користувач. Годі робити сайти для себе.

Якщо задати розмір шрифту в пікселях, це не вб’є всю доступність. Користувач може змінювати масштаб за допомогою CTRL+/- (на OSX замість клавіша CTRL CMD). Але можна зробити все краще.

Одиниці виміру REM

Якщо ви хоч якось знайомі зі світом веб-дизайну, ви точно чули про одиниці вимірювання REM. Якщо все ж не знаєте, REM – це спосіб вказати розмір шрифту на основі розміру шрифту кореневого елемента HTML. З їх допомогою також можна швидко змінити розміри у всьому проекті, змінивши розмір шрифту кореневого елемента (наприклад, під певний медіа запит/розмір екрану).

«REM одиниці являють собою розмір шрифту кореневого елемента (наприклад, розмір шрифту тега ). Якщо використовувати ці одиниці вимірювання для вказівки розміру шрифту кореневого елемента, ви отримаєте початкове значення.»

Як перевести REM у PX

Стандартний приклад: html розмір шрифту задано в 10px, параграф задано в 1,6 rem. 1,6 rem*10px = 16px.

Найпоширеніший сценарій, який я бачив, це встановлення кореневого розміру шрифту в 10px з допомогою REM. Це дозволяє легко і швидко переводити одні значення в інші, просто поділивши на 10.

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

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

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

Задайте розмір шрифту кореневого HTML елемента у відсотках. Відсотки будуть пов’язані з розміром шрифту в браузері за замовчуванням. Зазвичай ставлять розмір шрифту на 62,5%. 62,5% від 16px (стандартний розмір шрифта) складають 10px. Тобто 1,6 rem = 16px. Якщо користувач змінить розмір шрифту, наприклад, на 20px, то 1,6 rem будуть рівні 20px. Якщо користувач хоче шрифти ще більше, хай ставить. Щасливий дизайнер, щасливий розробник. З усіма числами легко працювати.

Ідеальний варіант – залишити розмір шрифту HTML на 100%, але тоді обчислення стануть трохи складніше. Наприклад, 16px будуть рівні 1rem, а 20px стануть 1,25 rem, 24px перетворяться в 1,5 rem і т. д.

Sass/SCSS в допомогу

Обчислювати всі ці числа в голові досить важко і довго. На щастя, вам не слід турбуватися, якщо ви використовуєте один з CSS препроцесорів Sass/SCSS, LESS. Всі цифри можна обчислювати за допомогою функцій.

А що з приводу EM одиниць вимірювання?

EM одиниці працюють майже так само, як REM, поки справа не стосується вкладеності. Мені ніколи не подобалися EM, особливо коли потрібно задавати розмір шрифту. Наприклад, візьмемо div з розміром шрифту 2em, додамо параграф зі шрифтом 2em. Розмір параграфа тепер 2em щодо div. Я швидко збиваюся в обчисленнях, де який розмір. Код швидко стає незручним. Саме цю проблему вирішує REM – розмір завжди прив’язується до кореневого елементу.

Що з приводу медіа запитів?

Отже, ми встановили, що значення в пікселях переписують значення браузера за замовчуванням, тому найкращий вихід – перевести всі пікселі в REM, вірно? Не зовсім.

У цій статті описуються ключові відмінності у використанні пікселів, EM і REM в медіа запитах https://zellwk.com/blog/media-query-units/). Прочитайте її і повертайтеся.

У підсумку, пікселі і REM в медіа запитах програють, коли необхідно змінити масштаб в деяких браузерах. EM в таких випадках стає найкращим варіантом. REM тут програють набагато більше, ніж пікселі, тому ми не будемо їх розглядати.

Все стає трохи складніше. У EM і пікселей є свої мінуси з медіа запитами, коли справа стосується відмінностей значень з плаваючою точкою. Якщо ви використовуєте min і max медіа запити в одному блоці коду, то вам доведеться попотіти, коли користувач почне змінювати масштаб браузера або розмір шрифту.

Пара прикладів:

Ми використовуємо шість цифр після крапки, так як окремі браузери не бачать різниці між 2-5 цифрами після крапки.

Приклад 1: масштаб у браузері встановлений у 100%, ширина вікна 640px

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

Приклад 1б: масштаб у браузері встановлений у 100%, ширина вікна 639px

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

Не можна використовувати 6 цифр після крапки для EM, це запускає обидва медіа запиту. Приклад 2: масштаб у браузері встановлений на 110%, ширина вікна 704px (так як 640px*110% = 704px)

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

Приклад 2б: масштаб у браузері встановлений на 110%, ширина вікна 705px

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

Ми не можемо використовувати дві цифри після крапки для EM. Нам залишилося використовувати 6dp. Це працює з зумом в браузерах. Однак… Приклад 3: масштаб у браузері встановлений у 100%, розмір шрифту 20px, ширина вікна 800 (640*125% = 800)

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

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

Який же вихід?

На жаль, відповіді немає. Поки браузери не вирішать проблеми з округленням, ви в пастці. Найпростіший вихід – не створювати min-width і max-width в одному блоці. Приклад:

body {
@media screen and (max-width: 63.99 em) {
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 в одну із сторін, замість того, щоб просто сказати браузеру, щоб той використовував варіант А або B;

зростає розмір файлу через перезаписів, несильно, але це варто врахувати.

У залежності від проекту, хто його розробляє і таких факторів, як бюджет (потрібно бути реалістами), пікселі будуть набагато простіше і швидше. Набагато простіше і швидше ігнорувати доступність.

Пам’ятайте, для кого ви створюєте сайти. Проблеми, порушені в цьому пості, актуальні на момент написання, проте постійні оновлення браузерів можуть залишити їх у минулому.