🕐 5 хв читання

Адаптивна типографіка

Конспект лекції: viewport-одиниці, rem-підхід, адаптивні розміри шрифтів та доступність

1. Viewport-залежні одиниці: vh і vw

Одиниці, що залежать від розмірів вікна браузера (viewport):

Одиниця Значення
1vh 1% від висоти вікна браузера
1vw 1% від ширини вікна браузера

100vh замість height: 100%

Щоб зробити блок на всю висоту екрану через height: 100%, потрібно задати height: 100% всім батьківським елементам у ланцюжку (html, body, обгортки). Це ненадійно та жорстко прив'язує до розмітки.

100vh вирішує це одним рядком без залежності від батьків:

.hero {
  height: 100vh;   /* Вся висота вікна */
}

Проблема vw та скролбар

100vw — це 100% ширини вікна без урахування скролбару. Якщо на сторінці є вертикальний скролбар (Windows, Linux), 100vw буде більше за доступну ширину, що спричинить горизонтальну прокрутку.

На macOS та мобільних пристроях скролбар накладається поверх контенту, тому проблема не виникає. Але на Windows/Linux скролбар займає місце (~17px).

Висновок: 100vw100%. Для ширини зазвичай краще використовувати відсотки.

2. Одиниці vmin і vmax

Одиниця Значення
1vmin 1% від меншого з двох значень (ширина або висота вікна)
1vmax 1% від більшого з двох значень (ширина або висота вікна)

Як це працює при зміні орієнтації

Орієнтація vmin поводиться як vmax поводиться як
Ландшафтна (ширина > висота) vh vw
Портретна (висота > ширина) vw vh

Приклад: адаптивний заголовок

.hero__title {
  font-size: 15vmin;   /* Авто-масштаб при будь-якій орієнтації */
}

Замість двох медіазапитів для портретної та ландшафтної орієнтації, vmin автоматично обирає менший вимір.

3. Обмеження viewport-залежних одиниць

Viewport-одиниці не підходять для побудови всього сайту:

  • Немає реальної залежності розміру шрифту від висоти вікна — на екранах 1080px та 900px різниця мінімальна
  • Неможливо відповідати дизайн-макету — розміри в пікселях стають непередбачуваними
  • Мобільні пристрої із схожими ширинами (360px vs 375px) отримають різний, але непотрібно різний розмір

Де viewport-одиниці доречні:

  • 100vh — повноекранні секції (hero-блоки)
  • 80vh — великі блоки з прив'язкою до висоти вікна
  • Проєкти без жорсткого дизайн-макету, де потрібен базовий адаптив

Основними одиницями залишаються px, %, em, rem.

4. Підхід з rem: одне значення для всіх пристроїв

Ідея: записати всі розміри в rem без медіазапиту, а в медіазапитах змінювати тільки font-size тегу <html>.

Desktop First підхід (пікселі)

/* Багато стилів у кожному медіазапиті */
@media (min-width: 1024px) {
  .card__title { font-size: 22px; }
  .card__text { font-size: 16px; }
  .card { padding: 20px; }
}
@media (max-width: 480px) {
  .card__title { font-size: 18px; }
  .card__text { font-size: 14px; }
  .card { padding: 12px; }
}

Підхід з rem

/* Усі розміри — без медіазапиту */
.card__title { font-size: 2.2rem; }
.card__text { font-size: 1.6rem; }
.card { padding: 2rem; }

/* У медіазапитах — тільки html font-size */
@media (min-width: 1024px) {
  html { font-size: 10px; }
}
@media (max-width: 480px) {
  html { font-size: 8px; }
}

Переваги: щоб збільшити все на сайті — достатньо змінити font-size тегу html. Щоб збільшити один елемент — змінити його значення у rem.

5. Користувацький розмір шрифту та відсотки

За замовчуванням font-size у браузері = 16px. Користувачі з порушеннями зору можуть змінити це значення в налаштуваннях.

Якщо ми задаємо html { font-size: 10px; } — налаштування користувача ігноруються. Щоб їх зберегти, використовуємо відсотки:

Перерахунок у відсотки

  • Потрібно 10px із 16px: 10 / 16 = 62.5%
  • Потрібно 8px із 16px: 8 / 16 = 50%
@media (min-width: 1024px) {
  html { font-size: 62.5%; }   /* = 10px від 16px */
}
@media (max-width: 480px) {
  html { font-size: 50%; }     /* = 8px від 16px */
}

Тепер якщо користувач змінить базовий розмір з 16px на 32px, наші rem-значення теж пропорційно збільшаться.

6. Дробні пікселі: чому округлюємо

Кожен піксель на екрані — це набір фізичних лампочок (RGB). Неможливо засвітити 0.18 лампочки. Тому всі значення в пікселях мають бути цілими числами.

Коли результат обчислень дає дробне число (наприклад, 8.18px), потрібно округлити до цілого. Браузер зробить це сам, але краще контролювати результат.

7. Ctrl+/- — це не zoom

Важлива відмінність між двома способами масштабування:

Спосіб Що відбувається
Zoom (pinch-to-zoom, тачпад) Сторінка збільшується як зображення, розкладка не змінюється
Ctrl+/Ctrl- Зменшується viewport — спрацьовують медіазапити, може відкритися мобільна версія

При Ctrl+ на 2K-моніторі window.innerWidth може показати 853px замість реальних 2560px. Верстка має коректно працювати і в такому режимі.

8. Доступність (Accessibility / a11y)

Інтернет — базова потреба для всіх людей, незалежно від фізичних особливостей. Основні інструменти доступності:

  • ARIA-атрибути — описують елементи для екранних читалок (screen readers)
  • Атрибут alt для <img> — обов'язковий: читалка озвучує цей текст, він же показується коли зображення не завантажилось
  • Атрибут title — підказка при наведенні (hover), працює для будь-якого елемента
  • Збільшення шрифту — в налаштуваннях браузера або системи; rem-одиниці забезпечують коректне масштабування

9. Веб-застосунок vs веб-сайт

Характеристика Веб-сайт Веб-застосунок (Web App)
UX (досвід) Перегляд сторінок, перехід за посиланнями Як нативний додаток: свайпи, анімації, offline
Приклади Новинні сайти, блоги Twitter, Gmail, Figma
Add to Home Screen Відкриється в браузері Відкриється як повноцінний додаток (без адресного рядка)

Сучасний JavaScript (React, React Native) дозволяє створювати веб-застосунки з UX, ідентичним нативним додаткам.

10. Підсумкова таблиця

Тема Ключове
vh / vw 1% від висоти / ширини viewport; 100vw ≠ 100% через скролбар
vmin / vmax 1% від меншого / більшого виміру viewport; автоматична адаптація до орієнтації
Обмеження viewport-одиниць Не підходять для всього сайту; доречні для hero-блоків (100vh) та проєктів без макету
Підхід з rem Усі розміри в rem, у медіазапитах — тільки html font-size
html font-size у % 62.5% = 10px; зберігає налаштування доступності користувача
Округлення пікселів Дробні значення в px потрібно округлювати — лампочку на 0.18 не засвітити
Ctrl+/- vs Zoom Ctrl+/- змінює viewport (медіазапити спрацьовують); zoom — масштабує як зображення
🔍
Почніть вводити назву лекції або тему