HTML & CSS

CSS Flexbox: Вирівнювання та Позиціонування

Глибоке занурення у вирівнювання Flex-елементів: justify-content, align-items, align-self, align-content та практика абсолютно ідеального центрування.

CSS Flexbox: Вирівнювання та Позиціонування

Ми створили сітку. Як тепер нею керувати?

У попередній статті про основи Flexbox ми навчились створювати Flex-контейнер, керувати напрямком його Головної осі (Main Axis) та дозволяти елементам переноситись на нові рядки за допомогою flex-wrap.

Але справжня "магія" Flexbox, за яку його так полюбили розробники по всьому світу, криється в його інструментах вирівнювання. Вам більше не потрібно вираховувати відсотки margins чи використовувати трюк absolute + transform: translate(-50%, -50%), щоб поставити блок рівно по центру екрану.

У Flexbox є чіткий набір властивостей, кожна з яких відповідає за певну вісь:

  • justify... — завжди працює з Головною віссю (Main Axis).
  • align... — завжди працює з Поперечною віссю (Cross Axis).

Давайте розберемо кожну з них детально.


Вирівнювання по Головній осі: justify-content

Властивість justify-content застосовується до Flex-контейнера. Вона визначає, як браузер має розподілити вільний простір всередині контейнера вздовж Головної осі. Якщо Головна вісь горизонтальна (flex-direction: row), то це вирівняє елементи по горизонталі. Якщо вертикальна (column) — по вертикалі.

Уявіть, що ваші елементи — це книги на полиці. Якщо полиця ширша за суму товщин усіх книг, у вас залишається вільне місце. justify-content вирішує, куди саме "запхати" це вільне місце: зліва від книг, між ними, навколо них чи справа.

Доступні основні значення:

flex-start

(За замовчуванням). Усі елементи притиснуті до початку Головної осі. Вільний простір залишається в кінці.

center

Усі елементи зсуваються в центр Головної осі. Вільний простір рівномірно розподіляється по краях.

flex-end

Усі елементи притиснуті до кінця Головної осі. Вільний простір залишається на початку.

space-between

Перший елемент притиснутий до початку, останній — до кінця. Увесь вільний простір ділиться на рівні відрізки між сусідніми елементами. Ідеально для навігаційних панелей.

space-around

Кожен елемент отримує однаковий простір навколо себе. Відстань між елементами буде вдвічі більшою, ніж відстань від крайніх елементів до стінок контейнера.

space-evenly

Увесь вільний простір ділиться на абсолютно рівні відрізки, як між елементами, так і між крайніми елементами та стінками. Відстань усюди однакова.
Preview
×
🔒localhost:3000

Анатомія space-between проти space-evenly: Часто розробники плутають ці два значення, хоча різниця очевидна:

  • space-between "приклеює" крайні елементи до стінок. Якщо вам треба зробити хедер, де логотип зліва, а кнопка входу — максимально справа, space-between впорається з цим за 1 рядок коду.
  • space-evenly гарантує, що відстань перед першим елементом дорівнює відстані після останнього, і вона точнісінько така ж, як і відстані між самими елементами. Це гарно виглядає для галерей карток однакового розміру.

Вирівнювання по Поперечній осі: align-items

Якщо justify-content працює з тим напрямком, в якому елементи "течуть", то align-items відповідає за перпендикулярну вісь (Cross Axis). Властивість застосовується також до Flex-контейнера, але діє на те, як елементи розташовуються всередині свого рядка по вертикалі (якщо flex-direction: row).

Значення цієї властивості вирішують знамениту проблему з "рівновисокими колонками" (коли фон бічної панелі мав закінчуватися там само, де текстовий контент, незалежно від наповнення).

Preview
×
🔒localhost:3000

Анатомія коду та значень align-items:

  • stretch (За замовчуванням): Це те, що робить Flexbox магічним для побудови сіток. Елементи не мають своєї власної висоти (якщо явно не задано). Замість цього вони "розтягуються", щоб заповнити всю висоту Батьківського контейнера. Завдяки цьому картки в рядку завжди будуть однакової висоти!
  • flex-start: Елементи приймають розмір свого вмісту (замість розтягування) і притуляються до верхнього краю контейнера (початку Поперечної осі).
  • flex-end: Те ж саме, але елементи притуляються до нижнього краю. Всі "звисають" вниз.
  • center: Елементи приймають розмір вмісту і центруються відносно висоти контейнера.
  • baseline: Елементи вирівнюються так, щоб їхній текстовий вміст (конкретніше — перша "лінія" тексту всередині) розташовувався на одній невидимій базовій лінії. У нашому демо зверніть увагу на червоний блок з великим шрифтом: під час baseline його текст знаходиться на одному рівні зі словами "Малий", "Великий" в інших блоках, навіть якщо верхні або нижні краї самих блоків не збігаються! Це критично важливо для вирівнювання іконок поруч із текстом різного розміру.

Індивідуальний бунтар: align-self

Властивість align-items контролює усіх дітей контейнера масово. Але що, якщо нам потрібно, щоб 99% елементів були по центру, а лише один конкретний притиснувся до низу?

Для цього існує властивість align-self, яка застосовується безпосередньо до Flex-елемента (дитини). Вона перевизначає те, що батько сказав через align-items для цього конкретного елемента.

Preview
×
🔒localhost:3000
Увага: У Flexbox немає властивості типу justify-self. Ви не можете змусити один елемент вишиковуватися певним чином по горизонталі, використовуючи магічне слово justify-self (ця властивість працює лише в CSS Grid). Якщо вам у flex-контейнері треба один елемент відсунути вліво, а всі інші вправо — ви використовуєте автоматичні відступи margin-left: auto; на потрібному елементі.

Священний Грааль Вебдизайну: Ідеальне Центрування (Perfect Centering)

Знаючи те, як працюють осі та вирівнювання, ми зараз розкриємо найбільший секрет Flexbox, який змінив життя розробників на "до" і "після".

Раніше на співбесідах фронтенд-девелопери годинами креслили на дошках методи відцентровування блоку по горизонталі та вертикалі в центрі екрана. Сьогодні правильна відповідь складається з трьох рядків коду на батьківському контейнері:

.hero-section {
    display: flex; /* 1. Вмикаємо розумний макет */
    justify-content: center; /* 2. Центруємо по горизонталі (Головна вісь) */
    align-items: center; /* 3. Центруємо по вертикалі (Поперечна вісь) */
}
Preview
×
🔒localhost:3000

Це працюватиме ідеально, навіть якщо всередині .login-card раптово додасться більше тексту і він стане значно вищим, або якщо на мобільному пристрої зміниться ширина екрану. Flexbox виконує важку математику за нас.


Вирівнювання багаторядкового контенту: align-content

Чи пам'ятаєте ви властивість flex-wrap: wrap з попередньої статті? Вона дозволяла елементам переноситись на нові лінії. Коли елементи дійсно перенеслися і створили багато ліній (рядків) всередині Flex-контейнера, виникає потреба вирівнювати не самі елементи всередині їхньої лінії, а цілі лінії (рядки) контенту відносно загальної висоти контейнера!

Для цього слугує властивість align-content. Можна вважати її аналогом justify-content, але для рядків по Поперечній осі.

Значення ті ж самі:

  • flex-start: Всі рядки збираються докупи у верхній частині контейнера.
  • flex-end: Всі рядки притискаються до низу.
  • center: Всі рядки кучкуються по центру.
  • space-between / space-around: Рядки розділяються рівними великими проміжками.
  • stretch (За замовчуванням): Рядки розтягуються, щоб заповнити весь простір контейнера (їхня власна висота збільшується).
Preview
×
🔒localhost:3000

Ключове правило align-content: Ця властивість працює виключно, якщо виконані ДВІ умови:

  1. Ви маєте flex-wrap: wrap або wrap-reverse.
  2. Контейнер достатньо високий (Cross Axis довша, ніж сума висот всіх рядків контенту).

Якщо елементи вмістилися всі в один рядок (nowrap), тоді align-content взагалі не матиме абсолютно ніякого ефекту, тому що лінії "тільки одна". Ви маєте користуватися лише align-items.


Резюме та Практика

Вітаємо, тепер ви знаєте про вирівнювання у сітках практично все, що треба:

  1. justify-content — вирівнює елементи вздовж Головної осі (зазвичай зліва направо, якщо це класичний row).
  2. align-items — вирівнює елементи вздовж Поперечної осі (зазвичай зверху вниз). Відповідає за те, розтягуються блоки чи ні.
  3. align-self — дозволяє одному елементу "не слухатись" align-items батька.
  4. align-content — вирівнює цілі рядки в багаторядковому макеті відносно Поперечної осі (коли в нас є і flex-wrap: wrap, і запасне вільне місце).

Практичні Навички рівня "Логіка"

Тепер ми контролюємо сітку та переміщуємо елементи в будь-яку точку. Але що, якщо один блок нам потрібен ширший за інший? Як зробити так, щоб блок тексту розтягнувся і зайняв 100% простору, який залишився поруч із фіксованим аватаром?

CSS Flexbox: Гнучкість Розмірів та Практичні Патерни

Як поділити простір чесно?

Відцентровувати об'єкти і створювати проміжки між ними — це чудово. Ми розібрали це у статтях про Основи та Вирівнювання.

Але що робить Flexbox "гнучким" (flexible)? Його здатність обчислювати динамічні розміри.

Уявіть, що у вас є 1000 пікселів вільного місця і 3 блоки.

  • Як зробити так, щоб кожен блок отримав рівно по третині простору, незалежно від обсягу тексту в ньому?
  • Як сказати браузеру: "Цей блок має зайняти весь вільний простір, який залишився після того, як бічне меню візьме свої фіксовані 250 пікселів"?

Саме тут на сцену виходять властивості Flex-елементів. До цього ми працювали переважно з Контейнером. Тепер керуватимемо поведінкою самих блоків усередині нього.


Три Стовпи Гнучкості: grow, shrink, basis

Поведінка будь-якого елемента у flex-контейнері визначається трьома властивостями. Запам'ятайте їхню хронологію:

  1. Спочатку елемент має свій початковий ідеальний розмір (flex-basis).
  2. Потім, якщо в контейнері залишився ВІЛЬНИЙ простір, елемент може розширитись, щоб поглинути його (flex-grow).
  3. Якщо навпаки, простору НЕ ВИСТАЧАЄ, елемент може стиснутись, щоб влізти (flex-shrink).

Розглянемо ці фази детально.

1. flex-basis — Початковий розмір

Перш ніж браузер почне рахувати вільне місце, він питає кожен елемент: "Який розмір тобі потрібен?". Властивість flex-basis визначає ідеальний, початковий розмір елемента уздовж Головної осі. Якщо flex-direction: row — це вісь X (аналог ширини). Якщо flex-direction: column — це вісь Y (аналог висоти).

.item-1 {
    flex-basis: 250px;
} /* Я хочу 250px */
.item-2 {
    flex-basis: 30%;
} /* Я хочу 30% від контейнера */
.item-3 {
    flex-basis: auto;
} /* Довжина мого контенту (за замовчуванням) */
.item-4 {
    flex-basis: 0;
} /* Я не маю початкового розміру, хочу нуль! */
Різниця між width та flex-basis:flex-basis впливає на ту вісь, яка зараз є "Головною". При column він встановлює висоту. width — це жорстке фізичне обмеження. Зазвичай рекомендується використовувати flex-basis у flex-контейнерах, оскільки це семантично пов'язане із механікою визначення вільного місця.

2. flex-grow — Здатність зростати (Жадібність)

Після того, як браузер роздав усім елементам їхній flex-basis, у контейнері може залишитись 500 пікселів вільного місця. Кому його віддати? За це відповідає flex-grow.

Він приймає числове значення без одиниць виміру (як пропорцію). Значення за замовчуванням — 0 (не забирати зайве місце).

Preview
×
🔒localhost:3000

Анатомія другого рядка демо: Елементи мали свій контент (flex-basis: auto). Перший взяв на себе умовні 50px ширини тексту, другий — 150px, третій — 60px. Залишилось 300px порожнечі. Оскільки кожен має flex-grow: 1 (сума "долей" = 3), браузер видав кожному по 100px зверху. Результат: 2-й елемент все одно ширший за інші, бо він був великим початково! Браузер поділив ПРИРІСТ, а не зрівняв їхні розміри в кінці. (Щоб зрівняти, нам потрібен flex-basis: 0 — про це нижче).

3. flex-shrink — Здатність стискатися

Ця властивість діє, коли розмір елементів сумарно більший за контейнер (і при цьому flex-wrap: nowrap, інакше вони б просто перенеслися на новий рядок). Браузер питає: "Так, у нас дефіцит 200px. З кого спишемо?".

Значення за замовчуванням — 1 (Всі стискаються однаково). 0 означає, що елемент "закріплений" і відмовляється стискатись.

.sidebar {
    width: 250px;
    flex-shrink: 0; /* Не стискай мій сайдбар за жодних обставин! */
}
.article {
    width: 800px;
    flex-shrink: 1; /* Звужуй текст, якщо користувач з планшета */
}
Preview
×
🔒localhost:3000


Стандарт Індустрії: Шорткат flex

Писати три властивості окремо (grow, shrink, basis) — довго, і це часто призводить до помилок (наприклад, забутий flex-shrink: 0 на іконці розтягує її в овал). У 99% випадків світова розробка використовує шорткат flex.

Синтаксис:

/* flex: <flex-grow> <flex-shrink> <flex-basis> */
.item {
    flex: 0 1 auto; /* Це магія за замовчуванням */
}

Давайте запам'ятаємо 4 класичних патерни:

1. flex: 1

Код: flex: 1 (аналог 1 1 0%). Поведінка: "Ігноруй мій контент, зроби нас усіх рівними!". Браузер каже: ваш початковий розмір 0 (basis). Тепер ділимо весь простір за flex-grow. Три елементи отримають по 33.33%, скільки б тексту в них не було.

2. flex: auto

Код: flex: auto (аналог 1 1 auto). Поведінка: "Рости і стискайся, але з повагою до мого розміру тексту". Схожий на flex: 1, але тут є база auto. Блок з довшим текстом завжди буде більшим і займе більшу частину залишкового простору.

3. flex: none

Код: flex: none (аналог 0 0 auto). Поведінка: "Мій розмір фіксований!". Ідеально підходить для аватарів, іконок або блоку логотипу в навігаційному меню. Він ніколи не розтягнеться і ніколи не звузиться, навіть якщо екран дуже маленький (він краще вийде за межі контейнера, ніж стиснеться).

4. flex: 0 0 250px

Поведінка: Жорсткий розмір у Flexbox. Не рости (0), не стискайся (0), завжди май базовий розмір (250px). Це надійний підхід для бічних панелей фіксованої ширини. Набагато безпечніше, ніж width: 250px.

В ідеальному світі...

Preview
×
🔒localhost:3000

Зміна Візуального Порядку: Властивість order

Одна з найпотужніших концепцій Flexbox полягає в тому, що він розділяє логічну розмітку (HTML) від візуальної παρουсiї (CSS).

За замовчуванням всі Flex-елементи мають order: 0. Браузер малює їх в тому порядку, у якому вони записані в HTML. Але якщо ми додамо одному з елементів позитивне або негативне число order, браузер намалює їх відповідно до цієї математичної послідовності. Від найменшого до найбільшого.

Preview
×
🔒localhost:3000

Коли це рятує життя? Уявіть мобільне меню адаптивного сайту. На комп'ютері: Логотип - Навігація - Вхід. На мобільному телефоні кнопка входу може зміститися під меню-бургер. За допомогою медіа-запитів (@media) ви просто змінюєте значення order для мобільних екранів і блоки переміщуються самі собою:

@media (max-width: 600px) {
    .nav-links {
        order: 3; /* Спустили меню в низ */
        width: 100%; /* Розтягнули на 100% */
    }
}
Критичний вплив на Доступність! Використання order або flex-direction: *-reverse розриває візуальний та логічний порядок. Коли людина використовує клавіатуру () для навігації сайтом, фокус переміщуватиметься на основі оригінальногo DOM (нашого HTML-коду!), а не того, що ви намалювали, змінивши order. На екрані кнопка може здаватись другою, а фокус полетить через всі елементи кудись вниз. Змінюйте order тільки для декоративних цілей. Якщо послідовність важлива, перепишіть ваш HTML.

Збираємо Все Разом: Практичні Патерни

Тепер ми знаємо як створити сітку, як її вирівняти, і як задати елементам гнучкий розмір. З цього набору інструментів можна побудувати 95% архітектури будь-якого сучасного сайту.

Розглянемо найпопулярніші макети реального світу.

Патерн 1: Компонент "Медіа Об'єкт"

Класичний блок "Аватарка автора і текст відгуку". Текст має розтягнутись і зайняти весь вільний правий простір, а аватарка має бути фіксованою, не стискатись, якщо тексту багато, але також не розтягуватись у висоту.

.comment {
    display: flex; /* Рядок за замовчуванням */
    gap: 1rem; /* Відступ між аватаром і текстом */
    align-items: flex-start; /* Щоб обидва блоки притулились до верху, інакше stretch розтягне аву */
}

.avatar {
    flex: none; /* Аналог 0 0 auto. Аватар ніколи не сплюснеться! */
    width: 64px;
    height: 64px;
    border-radius: 50%;
}

.content {
    flex: 1; /* Рости і заповнюй весь простір контейнера */
}
Preview
×
🔒localhost:3000

Патерн 2: Навігаційна панель із "розривом"

Рядок із лого зліва, меню по центру і профілем юзера справа.

.navbar {
    display: flex;
    align-items: center; /* Центруємо всі елементи по вертикалі */
}

.logo {
    margin-right: auto; /* Хак: "відштовхни" все, що праворуч від тебе, настільки, наскільки це можливо! */
}

.nav-links {
    /* Не задаємо марджінів, він стоятиме рівно там, де його притисне сусід */
}

.profile {
    margin-left: auto; /* Відштовхни все зліва! */
}
Preview
×
🔒localhost:3000

Проблема, якою згадують веб-розробку 90-х: якщо на сторінці мало контенту (2-3 рядки), підвал ("копірайт 2024") теліпається посеред білого екрану, а під ним — пустота вікна браузера. Як зробити так, щоб він завжди був притиснутим до низу? Flexbox вирішує це миттєво.

Побудова сторінки:

<body class="site-wrapper">
    <header>Шапка</header>
    <main class="content">Тут всього 2 рядки тексту</main>
    <footer>Підвал</footer>
</body>
.site-wrapper {
    display: flex;
    flex-direction: column; /* Вертикальна гоовна вісь */
    min-height: 100vh; /* Контейнер ОБОВ'ЯЗКОВО мінімум 100% висоти екрану! */
}

.content {
    flex: 1; /* Основний контент повинен вирости (flex-grow: 1), поглинаючи ВЕСЬ пустий простір! */
}
/* footer і header можуть не мати flex взагалі, вони просто візьмуть стільки висоти, скільки в них тексту */
/* .content розштовхає їх по краях! */
Preview
×
🔒localhost:3000

Патерн 4: Макет "Святий Грааль" (Holy Grail Layout)

Структура типу:

[Header]
[Nav (ліворуч)] [Основний текст] [Садбар (праворуч)]
[Footer]

Раніше вимагало жахливих табличних костилів.

/* Перетворюємо саму сторінку, як у Sticky Footer */
body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

header,
footer {
    /* Автоматично отримують висоту контенту і займають ширину 100% */
}

/* Середній блок огортає всі 3 колонки */
.main-wrapper {
    display: flex; /* Тепер тут горизонтальна вісь (row)! */
    flex: 1; /* Ця обгортка має розтягнутись (Sticky footer) */
}

.nav-left {
    flex: 0 0 100px; /* Фіксовано */
    order: -1; /* Візуально гарантуємо, що він зліва (навіть якщо в HTML він нижче основи) */
}

.main-content {
    flex: 1; /* Змістовна середина займає все залишкове місце */
}

.sidebar-right {
    flex: 0 0 120px; /* Фіксовано */
}
Preview
×
🔒localhost:3000

Як бачимо, флексбокс вкладається у флексбокс: body є вертикальним контейнером, а .main-wrapper є горизонтальним контейнером.


Резюме та Практика

Вітаємо, ви оволоділи Flexbox. Три ключові концепції, які ми розібрали для елементів:

  1. flex-grow дозволяє елементам розростатися і поглинати залишковий "зайвий" простір.
  2. flex-shrink дозволяє елементам зжиматися у тісноті.
  3. flex-basis визначає ідеальну теоретичну "вагу" (розмір) цього елемента до того, як розпочнуться математичні баталії за простір.

І найголовніше — ми зводимо це до зручних скорочень: flex: 1, flex: auto, flex: none.

Закріпимо наші знання на реальних задачах!

Practice Time: Рівень 1 (Базовий/Виправлення)

Practice Time: Рівень 2 (Логіка/Колекції)

Practice Time: Рівень 3 (Архітектура/Створення)

Сьогодні Flexbox покриває 90% потреб у створенні користувацьких інтерфейсів: від кнопок і навігаційних меню до багатошарових карток. Проте іноді з'являється задача: побудувати складний, нерівномірний двовимірний макет (з колонками і рядками, що перетинаються), наприклад, "шахову дошку" або складну галерею. У цьому випадку навіть Flexbox починає ускладнюватись. Коли закінчуються можливості Flexbox, в гру вступає CSS Grid Layout — його ми розглянемо в наступних статтях.

Copyright © 2026