Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «CSS flexbox макет». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**CSS Flexbox** - це модель верстки, яка розміщує елементи в один рядок або стовпець з автоматичним розподілом простору по двох осях: основній і поперечній. ```css .container { display: flex; justify-content: center; /* Основна вісь */ align-items: center; /* Поперечна вісь */ } ``` **Ключове:** `justify-content` керує основною віссю; `align-items` керує поперечною. Для двовимірних макетів використовуй CSS Grid.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**CSS Flexbox** - це модель верстки, яка розміщує елементи вздовж однієї осі (рядок або стовпець), автоматично розподіляючи простір, вирівнювання та розміри всередині контейнера. ## Теорія ### TL;DR - Flexbox схожий на конвеєрну стрічку: елементи самі розставляються, вирівнюються і змінюють розмір без фіксованих позицій - Головна різниця від float: flexbox дає передбачуване вирівнювання по двох осях, основній і поперечній - Використовуй для одновимірних макетів (навбар, кнопки); для двовимірних (дашборди) бери CSS Grid - `flex-direction` за замовчуванням - `row` (зліва направо) - `justify-content` керує основною віссю; `align-items` керує поперечною ### Швидкий приклад ```css .container { display: flex; /* Перетворює нащадків на flex items */ justify-content: space-between; /* Розподіляє елементи по основній осі */ align-items: center; /* Центрує по поперечній осі */ height: 100px; } ``` Три елементи всередині `.container` розтягнуться горизонтально з рівними проміжками і вирівняються по центру вертикально. Без float, без підрахунку margin. ### Порівняння з float-версткою До flexbox вертикальне центрування було відомою болячкою. Float-макети переносилися непередбачувано, а inline-block вимагав хаків з пробілами. В продакшені я бачив, як float-макети ламаються через проблеми з переносом частіше, ніж від майже будь-чого іншого в CSS. Flexbox замінює все це двома властивостями. Контейнер стає гнучкою одиницею. Елементи ростуть або стискаються, щоб заповнити доступний простір по основній осі. Не треба рахувати margin для рівних відступів: просто вказуєш контейнеру як розподілити вільний простір. ### Дві осі Кожен flex-контейнер має дві осі: - **Основна вісь** - визначається `flex-direction`. За замовчуванням `row` (зліва направо). - **Поперечна вісь** - перпендикулярна до основної. Коли `flex-direction: column`, основна вісь стає вертикальною. Це міняє місцями значення властивостей: `justify-content` тепер вирівнює вертикально, а `align-items` - горизонтально. Тут часто плутаються. ### Властивості контейнера | Властивість | Що робить | | --- | --- | | `flex-direction` | Напрямок головної осі: `row`, `row-reverse`, `column`, `column-reverse` | | `flex-wrap` | Перенос елементів: `nowrap` (за замовчуванням), `wrap`, `wrap-reverse` | | `justify-content` | Розподіл по основній осі: `flex-start`, `center`, `space-between`, `space-around`, `space-evenly` | | `align-items` | Вирівнювання по поперечній осі: `stretch`, `center`, `flex-start`, `flex-end`, `baseline` | | `align-content` | Розподіл кількох рядків (тільки при `flex-wrap: wrap`) | | `gap` | Відстань між елементами | ### Властивості елементів | Властивість | Що робить | | --- | --- | | `flex-grow` | Наскільки елемент росте відносно сусідів (за замовчуванням: `0`) | | `flex-shrink` | Наскільки стискається (за замовчуванням: `1`) | | `flex-basis` | Початковий розмір до росту або стиснення (за замовчуванням: `auto`) | | `flex` | Скорочення: `flex-grow flex-shrink flex-basis` | | `align-self` | Перевизначає `align-items` для одного елемента | | `order` | Змінює візуальний порядок без зміни HTML | Скорочення `flex: 1` розгортається в `flex: 1 1 0%`. Це означає "рости, стискайся, починай від нульової ширини." Саме так отримують колонки рівної ширини. ### Коли використовувати - Простий рядок або стовпець (навбар, група кнопок) - flexbox - Контент, який має переноситися (картки, теги) - flexbox з `flex-wrap: wrap` - Двовимірний макет (дашборд, сітка сторінки) - CSS Grid - Заміна старих float-багів - flexbox їх прибирає ### Як браузер це обробляє Коли браузер бачить `display: flex`, він створює flex formatting context (контекст форматування). Розраховує вільний простір по основній осі через flex-фактори зі скорочення `flex`, запускає кожен елемент через розрахунок гіпотетичного розміру, потім розподіляє залишок згідно з `justify-content`. Blink у Chrome робить це за один прохід reflow. Тому flexbox швидший за float для задач вирівнювання. ### Типові помилки **Забули `display: flex` на батьківському елементі:** ```css .container { /* display: flex відсутній */ } .item { flex: 1; } /* Ігнорується - елементи досі стакуються вертикально */ ``` `flex: 1` на нащадку не працює без flex-контейнера. Додай `display: flex` до `.container`. **`align-items` по неправильній осі при `column`:** ```css .container { display: flex; flex-direction: column; align-items: center; /* Центрує горизонтально, НЕ вертикально */ } ``` При `flex-direction: column` властивість `align-items` керує горизонтальним вирівнюванням. Для вертикального центрування в колонці використовуй `justify-content: center`. **Немає `flex-wrap` при переповненні:** ```css .container { display: flex; flex-wrap: nowrap; width: 200px; } .item { width: 100px; } /* 5 елементів = переповнення */ ``` `nowrap` стоїть за замовчуванням. При великій кількості елементів вони стискаються або виходять за межі. Додай `flex-wrap: wrap`. **Очікування рівних ширин без `flex: 1`:** ```css .container { display: flex; } .item { /* за замовчуванням flex: 0 1 auto - розмір по контенту */ } ``` Без `flex: 1` елементи не ділять простір порівну. Вони мають розмір відповідно до свого вмісту. Постав `flex: 1` на елементи, які мають рости рівномірно. **Конфлікт `min-width` і `flex-grow`:** ```css .container { display: flex; width: 300px; } .item1 { flex: 1; min-width: 100px; } .item2 { flex: 2; } ``` `item1` отримає свій мінімальний `100px` першим, `item2` забере решту (200px). Без `min-width` item1 може стиснутися більше, ніж очікується. ### Де зустрічається на практиці - React-компоненти навбара (Material-UI App Bar використовує flex всередині) - Bootstrap: utility-класи `.d-flex` - Tailwind: `flex`, `justify-between`, `items-center` для хедерів і карток - VS Code: бокова панель - flex для секцій, що змінюють розмір ### Питання для співбесіди **Q:** Яке значення `flex-direction` за замовчуванням і що змінює `row-reverse`? **A:** За замовчуванням `row` (зліва направо). `row-reverse` перевертає напрямок праворуч наліво, змінюючи початок і кінець основної осі. DOM-порядок не змінюється, тільки візуальний. **Q:** Яка різниця між `justify-content: space-between` і `space-around`? **A:** `space-between` ставить рівні проміжки між елементами, але не біля країв. `space-around` дає кожному елементу по половині проміжку з кожного боку, тому крайні елементи мають вдвічі менший відступ від краю контейнера, ніж проміжки між середніми. **Q:** Чим `align-content` відрізняється від `align-items`? **A:** `align-items` вирівнює елементи в одному рядку по поперечній осі. `align-content` розподіляє кілька рядків, коли `flex-wrap: wrap` створює більше одного ряду. Без переносу `align-content` нічого не робить. **Q:** `flex: 0 0 200px` і `margin: auto` - що відбудеться у вузькому контейнері? **A:** Елемент залишиться 200px і не стиснеться (немає `flex-shrink`). `margin: auto` поглинає вільний простір по основній осі і центрує елемент коли місце є. Якщо контейнер вужчий за 200px - елемент виходить за межі, якщо не встановлено `flex-wrap`. ## Приклади ### Навігаційна панель Типовий навбар: лого ліворуч, посилання праворуч. ```html <nav class="navbar"> <h1>Logo</h1> <ul> <li>Home</li> <li>About</li> <li>Contact</li> </ul> </nav> ``` ```css .navbar { display: flex; justify-content: space-between; /* Лого ліворуч, меню праворуч */ align-items: center; /* Обидва вертикально по центру */ padding: 0 20px; background: #333; } .navbar ul { display: flex; /* Вкладений flex: пункти меню в рядок */ list-style: none; gap: 1rem; } ``` Вкладені flex-контейнери працюють нормально. `ul` сам стає flex-контейнером для своїх `li`. ### Макет із фіксованим сайдбаром Сторінка з фіксованою боковою панеллю і гнучкою основною зоною. ```css .layout { display: flex; min-height: 100vh; } .sidebar { flex: 0 0 250px; } /* Фіксовані 250px, не росте, не стискається */ .main { flex: 1; } /* Займає весь простір що залишився */ .aside { flex: 0 0 200px; } /* Фіксовані 200px праворуч */ ``` `0 0 250px` означає "починай від 250px, не рухайся." `flex: 1` означає "візьми що залишилось." Ця комбінація - один з найпоширеніших flex-патернів у продакшені. ### Sticky footer Футер завжди внизу, навіть на коротких сторінках. ```css body { display: flex; flex-direction: column; /* Хедер, основний контент, футер стакуються вертикально */ min-height: 100vh; } main { flex: 1; /* Росте щоб заповнити залишок, відштовхуючи футер вниз */ } ``` `flex: 1` на `main` - це ключ. Він росте, щоб заповнити весь доступний вертикальний простір, тому футер залишається внизу незалежно від висоти контенту.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.