Позиціювання flex-елементів
Конспект лекції: align-items, align-self, flex-wrap, order, flex-grow та інші властивості Flexbox
1. align-items — вирівнювання по додатковій осі
Властивість align-items задається flex-контейнеру і керує розміщенням елементів
уздовж додаткової (cross) осі.
| Значення | Поведінка |
|---|---|
flex-start |
Притиснути до початку додаткової осі |
flex-end |
Притиснути до кінця додаткової осі |
center |
Центрувати по додатковій осі |
baseline |
Вирівняти по базовій лінії тексту (корисно, коли різний font-size) |
stretch (за замовчуванням) |
Розтягнути елементи на всю висоту контейнера |
flex-direction:
column, осі міняються місцями: головна йде зверху вниз, додаткова — зліва направо.
2. justify-content — вирівнювання по головній осі
Властивість justify-content керує розподілом елементів та вільного простору уздовж головної
(main) осі.
| Значення | Поведінка |
|---|---|
flex-start (за замовчуванням) |
Притиснути до початку головної осі |
flex-end |
Притиснути до кінця головної осі |
center |
Центрувати елементи |
space-between |
Крайні елементи притиснуті до меж, вільний простір — рівномірно між елементами |
space-around |
Рівні проміжки навколо кожного елемента (крайні = половина внутрішніх) |
space-evenly |
Усі проміжки абсолютно рівні (і між елементами, і від краю) |
Центрування модального вікна
.popup {
display: flex;
justify-content: center; /* по горизонталі */
align-items: center; /* по вертикалі */
}
3. flex-shrink — коефіцієнт стиснення
Властивість flex-shrink визначає, чи може елемент всередині flex-контейнера зменшуватися, коли
зменшується розмір екрану.
Синтаксис
flex-shrink: 1; /* за замовчуванням — елемент стискається */
flex-shrink: 0; /* елемент НЕ стискається */
Значення — будь-яке додатне число від 0 і вище. За замовчуванням — 1, тобто елемент зменшується
разом із контейнером.
Якщо поставити 0 — елемент зберігатиме свої розміри незалежно від ширини екрану.
Практичний приклад: пошуковий рядок
Уявімо пошуковий рядок з трьома частинами: підказка зліва, input по центру, кнопка «Шукати» справа. Якщо задати всім елементам розміри у відсотках — на маленьких екранах підказка розіб'ється на додаткові рядки, а текст кнопки обріжеться.
Рішення: заборонити підказці та кнопці стискатися:
/* Підказка і кнопка — фіксовані */
.hint, .button {
flex-shrink: 0;
}
/* Input займає решту простору */
.search-input {
flex-grow: 1;
}
4. flex-grow — коефіцієнт розтягування
Властивість flex-grow визначає, чи може елемент розтягуватися, щоб зайняти вільний простір.
Синтаксис
flex-grow: 0; /* за замовчуванням — не розтягується */
flex-grow: 1; /* розтягується, займає вільний простір */
flex-grow: 2; /* займає вдвічі більше, ніж flex-grow: 1 */
На відміну від flex-shrink, різні значення flex-grow дійсно дають різний результат.
Елемент із flex-grow: 2 займе вдвічі більше вільного простору, ніж елемент із flex-grow:
1.
Комбінація flex-shrink і flex-grow
Для пошукового рядка: підказка та кнопка не стискаються і не розтягуються, а input займає весь вільний простір:
.hint, .button {
flex-shrink: 0;
flex-grow: 0;
}
.search-input {
flex-grow: 1;
}
Тепер на будь-якому екрані ліва і права частини займають рівно стільки місця, скільки потрібно для їхнього вмісту, а input заповнює решту.
5. flex-basis та розміри елементів
Властивість flex-basis визначає початковий розмір елемента у flex-контейнері. Це аналог width
для горизонтальних та height для вертикальних flex-контейнерів.
Синтаксис
flex-basis: 250px;
flex-basis: 50%;
flex-basis: auto; /* розмір за вмістом */
Пріоритетність
flex-basis — це не жорстка ширина, а максимальна бажана величина. Якщо в
контейнері не вистачає місця, елементи стиснуться.
flex-basisважливіша заwidth— якщо задати обидва,widthігноруєтьсяmin-width/max-widthважливіші заflex-basis
У вертикальному flexbox
Якщо задати flex-direction: column, то flex-basis визначає висоту
елемента (замість ширини). Аналогічно: height ігнорується, а min-height / max-height
мають вищий пріоритет.
Правило
Не змішуйте flex-basis із width / height. Використовуйте або flex-basis,
або width (height) разом із min-/max- варіантами.
6. Скорочений запис flex
Властивості flex-grow, flex-shrink і flex-basis можна записати
скорочено через flex:
flex: <flex-grow> <flex-shrink> <flex-basis>;
Варіанти запису
| Запис | Еквівалент | Опис |
|---|---|---|
flex: auto |
flex: 1 1 auto |
Розтягується, стискається, розмір за вмістом |
flex: initial |
flex: 0 1 auto |
Значення за замовчуванням: не розтягується, стискається |
flex: none |
flex: 0 0 auto |
Не розтягується, не стискається — фіксований розмір |
flex: 1 |
flex: 1 1 0 |
Розтягується і стискається пропорційно |
flex: 2 |
flex: 2 1 0 |
Займає вдвічі більше простору, ніж flex: 1 |
Друге значення — число чи розмір?
Браузер автоматично визначає: якщо друге значення — просте число (1, 2, 3) — це flex-shrink.
Якщо це величина з одиницями (px, %, rem) — це flex-basis:
flex: 0 auto; /* flex-grow: 0, flex-basis: auto (flex-shrink: 1 за замовчуванням) */
flex: 1 200px; /* flex-grow: 1, flex-basis: 200px */
Спрощення пошукового рядка
.hint, .button {
flex: none; /* не стискається, не розтягується */
}
.search-input {
flex: 1; /* займає весь вільний простір */
}
7. Розподіл простору через flex
Замість відсотків можна використовувати flex для розподілу простору між елементами. Числа
визначають пропорції:
/* Три колонки: 20% + 30% + 50% */
.col-1 { flex: 2; } /* 2/10 = 20% */
.col-2 { flex: 3; } /* 3/10 = 30% */
.col-3 { flex: 5; } /* 5/10 = 50% */
Сума значень flex визначає «загальну кількість частин». Кожен елемент отримує свою частку.
Наприклад, 2 + 3 + 5 = 10 частин, і перший елемент займає 2/10 простору.
Переваги перед відсотками
- Додавання нових елементів — простір перерозподіляється автоматично
- Однакові
flex: 1для всіх — елементи завжди однакового розміру - На мобільних — вимикаєте
display: flex, і блоки стають звичайними div, які падають один під одного
Адаптивна колонкова верстка
.container {
display: flex;
}
.main { flex: 2; } /* 2/3 простору */
.sidebar { flex: 1; } /* 1/3 простору */
@media (max-width: 768px) {
.container {
display: block; /* відключаємо flex — блоки падають один під одного */
}
}
8. Властивість order
Властивість order змінює порядок відображення елементів у flex-контейнері без зміни
HTML. Працює лише в flexbox.
Синтаксис
order: 0; /* за замовчуванням */
order: 1; /* відобразити пізніше */
order: -1; /* відобразити раніше */
Значення — будь-яке ціле число (додатне або від'ємне). Чим менше число — тим раніше елемент з'являється:
- У горизонтальному flexbox: менше число — лівіше
- У вертикальному flexbox: менше число — вище
Приклад: картка новини
На десктопі: зображення → заголовок → теги → текст. На мобільному дизайнер хоче теги під текстом. Рішення —
додати order через медіазапит:
.card {
display: flex;
flex-direction: column;
}
@media (max-width: 480px) {
.card-tags {
order: 1; /* 1 > 0, тому теги переміщуються вниз */
}
}
На десктопі всі елементи мають order: 0 і відображаються в порядку HTML. На мобільному теги
отримують order: 1 і переміщуються вниз.
Семантика HTML
Перевірити семантику верстки можна, вимкнувши CSS у браузері. Без стилів сторінка повинна читатися логічно:
заголовки — це заголовки, списки — це списки (а не div зі span), навігація — це <nav> з
<ul>.
9. align-content — вирівнювання рядків flex-контейнера
Властивість align-content керує розподілом рядків багаторядкового
flex-контейнера по додатковій осі (працює лише з flex-wrap: wrap).
| Значення | Поведінка |
|---|---|
flex-start |
Рядки притиснуті до початку |
flex-end |
Рядки притиснуті до кінця |
center |
Рядки по центру |
space-between |
Крайні рядки притиснуті до меж, простір між рядками рівномірний |
space-around |
Рівні проміжки навколо кожного рядка |
stretch (за замовчуванням) |
Рядки розтягуються на всю висоту контейнера |
10. align-self — індивідуальне вирівнювання flex-елемента
Властивість align-self дозволяє перевизначити align-items для
одного конкретного flex-елемента по додатковій осі.
.container {
display: flex;
align-items: flex-start;
}
.button {
align-self: center; /* Тільки ця кнопка по центру */
}
| Значення | Поведінка |
|---|---|
auto (за замовчуванням) |
Успадковує значення align-items контейнера |
flex-start |
Притискає до початку додаткової осі |
flex-end |
Притискає до кінця додаткової осі |
center |
Центрує по додатковій осі |
stretch |
Розтягує на всю висоту рядка |
baseline |
Вирівнює по базовій лінії тексту |
Альтернатива: margin auto
Центрування одного елемента можна зробити і через margin-top: auto; margin-bottom: auto;, але
align-self: center — більш явний і семантичний спосіб.
11. Центрування елементів через margin: auto
У flex-контейнері margin: auto працює і по горизонталі, і по вертикалі (на відміну від
звичайного потоку, де margin-top: auto = 0).
.container {
display: flex;
width: 400px;
height: 400px;
}
.box {
width: 100px;
height: 100px;
margin: auto; /* Центрує і горизонтально, і вертикально */
}
margin auto у flex — розподіл елементів
| Елемент 1 | Елемент 2 | Результат |
|---|---|---|
margin-left: auto |
— | Елемент притискається вправо |
margin-right: auto |
margin-left: auto |
Елементи розходяться по кутах |
margin-right: auto |
margin-right: auto |
Обидва притискаються вліво |
margin-left: auto |
margin-left: auto |
Обидва притискаються вправо |
margin: auto для обох |
Обидва по центру | |
margin: auto керує окремими елементами, тоді як
justify-content — усіма елементами контейнера одразу.
12. position: fixed — фіксоване позиціювання
position: fixed поводиться майже як absolute, але з однією
ключовою відмінністю: елемент фіксується при прокрутці.
Спільне з absolute
- Ширина/висота рахуються за контентом (а не 100% батька)
- Елемент невидимий для сусідів і батька
- Можна задавати
width/heightнавіть інлайновим елементам - Керується через
top,right,bottom,left
Відмінність від absolute
| absolute | fixed | |
|---|---|---|
| Точка відліку | Найближчий батько з position: relative (або viewport, якщо немає) |
Завжди viewport (вікно браузера) |
| При прокрутці | Прокручується разом зі сторінкою | Залишається на місці |
| Реагує на relative батька | Так | Ні |
Типові приклади fixed
- Фіксована шапка — завжди вгорі при прокрутці
- Модальне вікно — перекриває весь екран, не рухається
- Кнопка «Нагору» — завжди в куті екрана
- Чат-бот — віконце підтримки внизу справа
- Бічне меню (dashboard) — фіксована навігація зліва
/* Модальне вікно — fixed замість absolute */
.popup {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 9999; /* гарантовано поверх усього */
display: flex;
justify-content: center;
align-items: center;
}
13. display: none — повне приховування
display: none повністю прибирає елемент зі сторінки — ніби його видалили з HTML.
| Спосіб приховування | Видимий? | Займає місце? | Інтерактивний? | Доступний для скрінрідерів? |
|---|---|---|---|---|
display: none |
Ні | Ні | Ні | Ні |
opacity: 0 |
Ні | Так | Так (можна клікнути) | Так |
Візуальне приховування (clip-path) |
Ні | Ні | Так (Tab) | Так |
display: none— елемент не повинен існувати на сторінці (закрите модальне вікно, прихований таб)- Візуальне приховування (
clip-path) — елемент потрібен, але не видимий (текст для скрінрідерів, приховані label)
14. Показ/приховування через класи (popup-паттерн)
Класичний підхід для модальних вікон, випадаючих меню, табів:
/* Базовий стан — приховано */
.popup {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: none; /* приховано */
}
/* Активний стан — показано */
.popup--active {
display: flex; /* перекриває display: none */
justify-content: center;
align-items: center;
}
Як це працює з JavaScript
// Закрити popup при кліку на хрестик
document.querySelector('.popup__close')
.addEventListener('click', function() {
document.querySelector('.popup--active')
.classList.remove('popup--active');
});
JavaScript лише додає/видаляє клас. Вся стилізація — у CSS.
.popup--active повинен бути нижче
в CSS, ніж .popup. При однаковій специфічності браузер застосує той, що стоїть останнім.
15. Специфічність CSS-селекторів
Коли до одного елемента застосовуються кілька правил з однаковою властивістю — браузер обирає за коефіцієнтом специфічності.
Формула: 4 числа
| Позиція | Що рахуємо | Приклад |
|---|---|---|
| A | Inline-стиль (style="...") |
0 або 1 |
| B | Кількість id |
#header → 1 |
| C | Кількість класів, псевдокласів, атрибутів | .nav:hover → 2 |
| D | Кількість елементів (тегів), псевдоелементів | div::before → 2 |
Приклади розрахунку
| Селектор | A | B | C | D |
|---|---|---|---|---|
span |
0 | 0 | 0 | 1 |
.slogan |
0 | 0 | 1 | 0 |
#slogan |
0 | 1 | 0 | 0 |
style="..." |
1 | 0 | 0 | 0 |
ul > .widget.socials |
0 | 0 | 2 | 1 |
.widget.socials |
0 | 0 | 2 | 0 |
div.widget:hover |
0 | 0 | 2 | 1 |
16. Що НЕ впливає на специфічність
- Дочірній селектор
>— не додає ваги - Сусідній селектор
+— не додає ваги - Загальний сусідній
~— не додає ваги - Вкладений селектор (пробіл) — не додає ваги
/* Обидва мають специфічність 0,0,2,1 */
ul > .widget.socials { ... }
ul .widget.socials { ... }
> «звужує» вибірку, але не
підвищує специфічність.
17. Однакова специфічність → порядок у CSS
Якщо два селектори мають однакову специфічність, перемагає той, що розташований нижче у CSS-файлі.
/* Специфічність обох: 0,0,1,0 */
.slogan { font-size: 40px; } /* ← програє */
.text { font-size: 20px; } /* ← переможе */
class="slogan
text" чи class="text slogan". Має значення лише порядок правил у CSS.
Практичне застосування
Тому сторонні стилі (бібліотеки, віджети) підключають до ваших стилів:
<!-- 1. Спочатку — сторонні стилі -->
<link rel="stylesheet" href="widget.css">
<!-- 2. Потім — ваші стилі -->
<link rel="stylesheet" href="style.css">
Завдяки цьому ваш селектор з такою ж специфічністю перекриє стилі бібліотеки.
18. Дочірній селектор > та комбінування з тегом
Вкладений vs дочірній
| Селектор | Що обирає |
|---|---|
.widget div |
Усі div всередині .widget (на будь-якому рівні
вкладеності)
|
.widget > div |
Тільки безпосередні дочірні div (перший рівень) |
Комбінування класу з тегом
/* Будь-який елемент з класом .card */
.card { ... }
/* Тільки <article> з класом .card */
article.card { ... }
div.card жорстко прив'язує стилі до
<div>. Якщо потім змінити тег на <article> — стилі зламаються.
Стилізуйте за класами.
19. !important — коли інших варіантів немає
!important підвищує пріоритет конкретної властивості (не всього селектора) вище
за inline-стилі:
span {
font-size: 10px !important; /* переможе навіть style="font-size: 20px" */
}
Якщо є два !important — перемагає той, у кого вища специфічність селектора.
!important — це «антипатерн». Ознака помилки в архітектурі CSS. Його дуже
важко «виковиряти» з коду потім.
- Не використовуйте без крайньої потреби
- Якщо використали — завжди залишайте коментар, чому
- Допустимі випадки: швидкий хотфікс, перекриття стороннього віджета без доступу до його CSS
20. Рекомендації щодо архітектури CSS
- Стилізуйте за класами, не за id (id — для JavaScript)
- Максимально плоска структура: один клас → один селектор (
.popup-box,.popup-close) - Уникайте глибокої вкладеності:
.page .main .content h1— погано - Краще:
.main-title— просто, зрозуміло, низька специфічність - Сторонні бібліотеки підключайте перед власними стилями
- Не використовуйте
!importantу звичайній роботі
.popup,
.popup__box, .popup--active — усі мають специфічність 0,0,1,0.
21. Підключення шрифтів — @font-face
Конструкція @font-face описує файл шрифта для браузера. На кожне начертання —
окремий @font-face.
/* Звичайне начертання */
@font-face {
font-family: "PT Sans";
src: url("../fonts/pt-sans-regular.woff2") format("woff2");
font-weight: 400;
font-style: normal;
}
/* Жирне начертання */
@font-face {
font-family: "PT Sans";
src: url("../fonts/pt-sans-bold.woff2") format("woff2");
font-weight: 700;
font-style: normal;
}
Як браузер обирає файл
Браузер порівнює три параметри елемента з описом у @font-face:
font-family— збігається?font-weight— збігається?font-style— збігається?
Якщо всі три збіглися — завантажується відповідний файл шрифта.
Запасний шрифт (font stack)
body {
font-family: "PT Sans", Arial, sans-serif;
}
sans-serif або serif).
| Сімейство | Опис | Приклад |
|---|---|---|
sans-serif |
Без засічок (гротеск) | Arial, Helvetica |
serif |
Із засічками (антиква) | Times New Roman, Georgia |
22. Зчитування параметрів тексту з макета
У Photoshop/Figma для кожного текстового шару зчитуємо:
| Параметр | CSS-властивість | Примітка |
|---|---|---|
| Сімейство шрифта | font-family |
PT Sans, Roboto тощо |
| Начертання (Bold, Regular…) | font-weight |
400 = Regular, 700 = Bold |
| Розмір шрифта | font-size |
Переконайтесь, що одиниці — пікселі |
| Висота рядка | line-height |
Якщо «Auto» → normal |
| Uppercase іконка | text-transform: uppercase |
— |
| Колір | color |
Піпетка або панель властивостей шару |
line-height для заголовків в одну стрічку!
Дизайнери часто використовують висоту рядка для відступів. Якщо текст стане дворядковим — міжрядковий
інтервал буде занадто великим. Ставте line-height: normal або підберіть адекватне значення.
23. Формати зображень
| Формат | Тип | Прозорість | Стиснення | Для чого |
|---|---|---|---|---|
| JPEG | Растр | Ні | З втратою якості | Фотографії, фони, ілюстрації |
| PNG | Растр | Так | Без втрати якості | Логотипи, елементи з прозорістю |
| SVG | Вектор | Так | Мінімальний розмір | Іконки, графіки, прості ілюстрації |
| WebP | Растр | Так | Краще за JPEG/PNG | Сучасна альтернатива JPEG та PNG |
24. Підсумкова таблиця
| Тема | Ключове |
|---|---|
| align-items | Вирівнювання по додатковій осі: flex-start, center, flex-end,
baseline, stretch |
| justify-content | Вирівнювання по головній осі: center, space-between,
space-around, space-evenly |
| flex-shrink | Коефіцієнт стиснення: 1 (за замовчуванням) — стискається, 0 — ні |
| flex-grow | Коефіцієнт розтягування: 0 (за замовчуванням), 1+ — займає вільний простір |
| flex-basis | Початковий розмір елемента; пріоритетніша за width/height |
| flex (скорочений) | flex: none — фіксований; flex: 1 — займає простір; flex: auto — розтягується за вмістом |
| Розподіл простору | Числа flex визначають пропорції: flex: 2 + flex: 1 = 2/3 + 1/3 |
| order | Зміна порядку відображення без зміни HTML; менше число — раніше |
| align-content | Вирівнювання рядків у багаторядковому flex-контейнері (flex-wrap: wrap) |
| align-self | Індивідуальне вирівнювання flex-елемента; перевизначає align-items контейнера |
| margin: auto у flex | Центрує елемент і по горизонталі, і по вертикалі; керує окремими елементами |
| position: fixed | Як absolute, але фіксується при прокрутці; завжди відносно viewport |
| display: none | Повне приховування; елемент «не існує» (не займає місце, не інтерактивний) |
| Popup-паттерн | .popup (display: none) + .popup--active (display:
flex); JS додає/видаляє клас
|
| Специфічність | 4 числа: inline / id / класи+псевдокласи / теги+псевдоелементи |
| Однакова специфічність | Перемагає правило, що стоїть нижче в CSS |
| !important | Підвищує пріоритет однієї властивості; антипатерн, уникайте |
| Селектор > | Дочірній (перший рівень); не впливає на специфічність |
| @font-face | Описує файл шрифта; один @font-face = одне начертання |
| font stack | Завжди: кастомний → системний → sans-serif/serif |
| Формати зображень | JPEG — фото; PNG — прозорість; SVG — іконки; WebP — сучасна альтернатива |