Адаптивна типографіка
Конспект лекції: 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).
Висновок: 100vw ≠ 100%. Для ширини зазвичай краще використовувати відсотки.
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 — масштабує як зображення |