Верстка гумового макета
Конспект лекції: фіксована, гумова та адаптивна верстка, відносні одиниці, відсоткові розміри
1. Фіксована, гумова та адаптивна верстка
Існує три основних підходи до верстки:
| Підхід | Одиниці | Поведінка |
|---|---|---|
| Фіксована | Пікселі (px) |
Розміри жорстко задані. При зменшенні вікна з'являється горизонтальна прокрутка |
| Гумова (fluid) | Відсотки (%) |
Елементи пропорційно змінюють розмір разом із батьківським блоком, але залишаються на своїх місцях |
| Адаптивна (responsive) | % + медіазапити |
На певній точці елементи змінюють розташування (наприклад, дві колонки стають однією) |
Більше 60–80 % користувачів сучасних сайтів заходять з мобільних пристроїв, тому адаптивність — обов'язкова вимога.
2. Ширина у відсотках
Ширина у відсотках розраховується від ширини батьківського елемента.
/* Фіксована верстка */
.container { width: 1000px; }
.content { width: 650px; }
.sidebar { width: 350px; }
/* Гумова верстка */
.content { width: 65%; }
.sidebar { width: 35%; }
Блочний елемент за замовчуванням займає 100 % доступної ширини, тому батьківському контейнеру width:
100% можна не задавати.
Коли вікно браузера звужується — ширина батьківського блоку зменшується, а разом з нею пропорційно зменшуються й дочірні елементи.
3. Висота у відсотках
Висота у відсотках працює лише тоді, коли батьківський елемент має явно задану висоту.
/* Не працює — висота батька auto */
.parent { }
.child { height: 50%; } /* ігнорується */
/* Працює — висота батька задана явно */
.parent { height: 400px; }
.child { height: 50%; } /* = 200px */
auto і визначається контентом, тому відсоток від
auto браузер обчислити не може.
Фіксувати висоту для блоків з динамічним контентом — погана практика: якщо контенту більше, він виллється за межі блоку.
4. Відсотки для position: absolute і fixed
Для абсолютно позиціонованих елементів розміри у відсотках беруться не від прямого батька, а від найближчого
предка з position: relative (контексту позиціонування).
.wrapper {
position: relative;
width: 500px;
height: 300px;
}
.parent {
width: 100px;
height: 100px;
}
.child {
position: absolute;
top: 0;
left: 0;
width: 100%; /* = 500px (від wrapper) */
height: 100%; /* = 300px (від wrapper) */
}
Для position: fixed розміри завжди беруться від viewport — вікна браузера.
width: 100% = вся ширина екрана, height: 100% = вся висота екрана.
5. max-width і min-width
Коли ширина задана у відсотках або не обмежена — на широких екранах блок розтягується занадто сильно: текст стає важко читати, зображення надмірно обрізаються.
.container {
width: 100%;
max-width: 1280px;
margin-left: auto;
margin-right: auto;
}
| Властивість | Що робить |
|---|---|
max-width |
Обмежує максимальну ширину. Блок «гумовий», але ніколи не стане ширшим за вказане значення |
min-width |
Обмежує мінімальну ширину. Якщо екран вужчий — з'являється горизонтальна прокрутка |
max-width обов'язково додайте margin-left:
auto і margin-right: auto, щоб центрувати блок. Інакше він притиснеться до лівого
краю.
min-width — це тимчасове рішення: воно не позбавляє горизонтальної прокрутки. Для коректного
відображення на вузьких екранах потрібна адаптивна верстка з медіазапитами.
6. margin-left: auto та margin-right: auto — запис
Для центрування блоку краще писати розгорнуті властивості замість скороченого запису:
/* Скорочений запис — задає зайві margin-top і margin-bottom */
.container { margin: 0 auto; }
/* Розгорнутий запис — задає лише потрібне */
.container {
margin-left: auto;
margin-right: auto;
}
Проблема скороченого запису: margin: 0 auto обнулює margin-top і margin-bottom.
Якщо десь вище у CSS ви задали вертикальні відступи — вони будуть перезаписані. З розгорнутими властивостями
цього конфлікту не буде.
7. margin і padding у відсотках
Контрінтуїтивне правило: і горизонтальні, і вертикальні margin та
padding у відсотках розраховуються від ширини батьківського елемента.
.wrapper { width: 1000px; }
.card {
margin: 1%; /* top, right, bottom, left — усі = 10px */
padding: 1%; /* top, right, bottom, left — усі = 10px */
}
margin-top, margin-bottom,
padding-top, padding-bottom у відсотках беруться від ширини
батька, а не від висоти. Це стандартна поведінка CSS.
На практиці відступи зазвичай задають у пікселях, тому ця особливість рідко створює проблеми. Але вона лежить в основі цікавої техніки — збереження пропорцій блоку.
8. Техніка збереження пропорцій блоку (padding-hack)
Оскільки padding-bottom у відсотках рахується від ширини батьківського елемента, ми можемо
створити блок, який завжди зберігає свої пропорції:
.aspect-ratio-box {
height: 0;
padding-bottom: 100%; /* квадрат */
overflow: hidden;
}
Принцип роботи:
height: 0— висота контенту не впливає на розмір блокуpadding-bottom: 100%— висота блоку дорівнює його ширині (бо padding рахується від ширини батька)overflow: hidden— обрізає контент, що виходить за межі
Значення padding-bottom для різних пропорцій:
| Пропорція | padding-bottom |
|---|---|
| 1:1 (квадрат) | 100% |
| 16:9 (відео) | 56.25% |
| 4:3 | 75% |
| 3:2 | 66.66% |
9. Вбудовування відео з YouTube (реальний приклад)
Найпоширеніший випадок застосування padding-hack — створення гумового контейнера для вбудованого відео:
<!-- HTML -->
<div class="video-wrapper">
<iframe src="https://www.youtube.com/embed/VIDEO_ID"
allowfullscreen></iframe>
</div>
/* CSS */
.video-wrapper {
position: relative;
height: 0;
padding-bottom: 56.25%; /* 16:9 */
overflow: hidden;
}
.video-wrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
Як це працює:
iframeзposition: absoluteне впливає на висоту батька- Висота
.video-wrapperвизначається лишеpadding-bottom iframeрозтягується на 100 % ширини та висоти обгортки- При зміні ширини екрана відео зберігає пропорції 16:9
aspect-ratio, яка вирішує цю задачу
елегантніше: aspect-ratio: 16 / 9. Підтримується всіма сучасними браузерами (Chrome 88+,
Firefox 89+, Safari 15+). Але padding-hack досі зустрічається у старих проєктах.
10. font-size у відсотках
Розмір шрифту у відсотках рахується від font-size батьківського елемента:
.parent { font-size: 20px; }
.child { font-size: 50%; } /* = 10px */
Практичний приклад: кнопка <button>
Елемент <button> має дефолтний font-size: 13.333px, який не наслідується від
батька. Щоб розмір тексту кнопки збігався з розміром тексту контейнера:
button {
font-size: 100%; /* наслідує розмір від батьківського елемента */
}
Це дозволяє змінювати розмір шрифту в одному місці (на батьківському елементі), і він автоматично оновиться у кнопці.
11. Flexbox: повторення ключових концепцій
Дві осі
У Flexbox є головна (main) і додаткова (cross) осі. Замість «ліворуч/праворуч» коректно казати «початок/кінець осі».
Висота елементів у рядку
За замовчуванням flex-елементи у рядку розтягуються на однакову висоту — це поведінка align-items:
stretch. Колонки однакової висоти — це дефолтна поведінка Flexbox, не потрібно нічого додатково
налаштовувати.
Зміна напрямку додаткової осі
Напрямок додаткової осі можна змінити двома способами:
| Спосіб | Пояснення |
|---|---|
flex-direction: column |
Головна ось стає вертикальною → додаткова стає горизонтальною |
flex-wrap: wrap-reverse |
Елементи переносяться у зворотному напрямку → додаткова ось змінює напрямок |
12. Flexbox замість float
Float для створення колонок — застарілий підхід. Всі сучасні браузери повноцінно підтримують Flexbox.
Flexbox автоматично скасовує float
.news-item {
float: left; /* старий підхід для колонок */
}
.news {
display: flex; /* float автоматично перестає працювати */
}
Якщо для батьківського елемента задано display: flex, то float дочірніх елементів
ігнорується. Це закладено в специфікацію Flexbox.
Проблеми float, які вирішує Flexbox
- Батьківський блок «втрачає» висоту (потрібен clearfix-хак)
- Складніше керувати вирівнюванням та розподілом простору
- Потрібні додаткові хаки для однакової висоти колонок
float, який використовується для колонок — сміливо
замінюйте на display: flex. Залишайте float лише для його початкового призначення
— обтікання зображень текстом.
13. Clearfix — хак для float (історична довідка)
Коли float використовувався для колонок, батьківський блок «схлопувався» — не враховував висоту
float-елементів. Для виправлення застосовували clearfix:
.clearfix::after {
content: "";
display: table;
clear: both;
}
У сучасній верстці з Flexbox clearfix не потрібен — це повністю застарілий прийом.
14. Підсумкова таблиця: відсотки у CSS
| Властивість | Від чого рахуються % | Примітка |
|---|---|---|
width |
Ширина батьківського елемента | Працює завжди |
height |
Висота батьківського елемента | Тільки якщо висота батька задана явно |
margin (всі сторони) |
Ширина батьківського елемента | Навіть вертикальні — від ширини! |
padding (всі сторони) |
Ширина батьківського елемента | Навіть вертикальні — від ширини! |
font-size |
font-size батьківського елемента |
Є кращі одиниці (em, rem) |
width / height при position: absolute |
Розміри найближчого предка з position: relative |
Не від прямого батька! |
width / height при position: fixed |
Розміри viewport (вікна браузера) | Завжди від вікна |