Як працює CSS Flexbox
Привіт:) CSS Flexbox — це технологія для створення складних гнучких макетів для правильного розміщення елементів на сторінці.
Розглянемо можливості CSS Flexbox із наочними прикладами.
display: flex
Є сторінка:

На ній розміщено 4 div різних розмірів, які знаходяться всередині сірого div. У кожного div є властивість display: block. Тому кожен блок займає всю ширину рядка. Щоб працювати з CSS Flexbox, потрібно зробити контейнер flex-контейнером. Робиться це так:
#container {
display: flex;
}

Тут у блоків з'явилася властивість flex-контекст, яка надалі дозволить ними керувати набагато простіше, ніж з використанням стандартного CSS.
до змісту ↑flex-direction
У flex-контейнера є дві осі: головна та перпендикулярна їй.

За замовчуванням усі елементи розташовуються вздовж головної осі — зліва направо. Саме тому блоки в попередньому прикладі вишикувалися в лінію, коли ми застосували display: flex. А ось flex-direction дозволяє крутити головну вісь.
#container {
display: flex;
flex-direction: column;
}

Зверніть увагу, що flex-direction: column не вирівнює блоки по осі, перпендикулярної до головної. Головна вісь сама змінює своє розташування і тепер спрямована зверху вниз.
Є ще декілька властивостей для flex-direction: row-reverse і column-reverse.

justify-content
Відповідає за вирівнювання елементів по головній осі:
#container {
display: flex;
flex-direction: row;
justify-content: flex-start;
}
Justify-content може набувати 5 значень:
flex-startflex-endcenterspace-betweenspace-around

Space-between визначає однакову відстань між блоками, але не між контейнером і блоками. Space-around також визначає однакову відстань між блоками, але тепер відстань між контейнером і блоками дорівнює половині відстані між блоками.
align-items
Якщо justify-content працює з головною віссю, то align-items працює з віссю, перпендикулярною до головної осі. Повернемося до flex-direction: row та пройдемося командами align-items:
flex-startflex-endcenterstretchbaseline

Для align-items: stretch висота блоків повинна дорівнювати auto. Для align-items: baseline теги параграфа прибирати не потрібно, інакше вийде так:

Щоб краще розібратися в тому, як працюють осі, об'єднаємо justify-content з align-items і подивимося, як працює вирівнювання по центру для двох властивостей flex-direction:

align-self
Дозволяє вирівнювати елементи окремо:
#container {
align-items: flex-start;
}
.square#one {
align-self: center;
}
Для двох блоків застосуємо align-self, а для інших — align-items: center та flex-direction: row.

flex-basis
Відповідає за початковий розмір елементів до того, як їх змінять інші властивості CSS Flexbox:

Flex-basis впливає на розмір елементів уздовж головної осі. Подивимося, що станеться, якщо ми змінимо напрямок головної осі:

Тут довелося змінити і висоту елементів: flex-basis може визначати висоту елементів і їх ширину залежно від напрямку осі.
flex-grow
Ця властивість складніша. Для початку задамо блокам однакову ширину 120px:

За замовчуванням значення flex-grow рівне 0. Це означає, що блокам заборонено збільшуватися в розмірах. Задамо flex-grow рівним 1 для кожного блоку:

Тепер блоки зайняли місце в контейнері, що залишилося. Але що означає flex-grow: 1? Спробуємо зробити flex-grow рівним 999:

Нічого не сталося. Так вийшло через те, що flex-grow набуває не абсолютних значень, а відносних. Це означає, що не важливо, яке значення у flex-grow, важливо яке воно по відношенню до інших блоків:

Спочатку flex-grow кожного блоку дорівнює 1, у сумі вийде 6. Отже, наш контейнер розділений на 6 частин. Кожен блок займатиме 1/6 частину доступного простору в контейнері. Коли flex-grow третього блоку стає рівним 2, контейнер ділиться на 7 частин: 1+1+2+1+1+1. Тепер третій блок займає 2/7 простору, решта — по 1/7. І так далі.
flex-grow працює лише для головної осі, поки ми не змінимо її напрямок.
flex-shrink
Пряма протилежність flex-grow. Визначає, наскільки блоку можна зменшитися у розмірі. flex-shrink використовується, коли елементи не вміщуються у контейнер. Ви визначаєте, які елементи мають зменшитись у розмірах, а які — ні. За замовчуванням значення flex-shrink для кожного блоку дорівнює 1. Це означає, що блоки стискатимуться, коли контейнер зменшуватиметься. Задамо flex-grow та flex-shrink рівними 1:

Тепер змінимо значення flex-shrink для третього блоку на 0. Йому заборонили стискатись, тому його ширина залишиться рівною 120px:

Flex-shrink ґрунтується на пропорціях. Тобто, якщо у першого блоку flex-shrink дорівнює 6, а в інших він дорівнює 2, то це означає, що перший блок буде стискатися втричі швидше, ніж інші.
flex
Замінює flex-grow, flex-shrink та flex-basis. Значення за замовчуванням: 0 (grow) 1 (shrink) auto (basis).
Створимо два блоки:
.square#one {
flex: 2 1 300px;
}
.square#two {
flex: 1 2 300px;
}
В обох однаковий flex-basis. Це означає, що обидва будуть шириною 300px (ширина контейнера: 600px плюс margin і padding). Але коли контейнер почне збільшуватися в розмірах, перший блок (з більшим flex-grow) буде збільшуватися вдвічі швидше, а другий блок (з найбільшим flex-shrink) стискатиметься вдвічі швидше:

Як із CSS Flexbox змінюється розмір?
Коли збільшується перший блок, він не стає вдвічі більше другого, і коли зменшується другий, він також не стає вдвічі менше першого. Це відбувається через те, що flex-grow та flex-shrink відповідають за темпи зростання та скорочення.
Трохи математики. Початковий розмір контейнера: 640px. Віднімемо по 20px з кожного боку для padding, і у нас залишиться 600px для двох блоків. Коли ширина контейнера дорівнює 430px (втрата 210px), перший блок (flex-shrink: 1) втрачає 70px. Другий блок (flex-shrink: 2) втрачає 140px. Коли контейнер стискається до 340px, ми втрачаємо 300px. Перший блок втрачає 100px, другий — 200px. Те саме відбувається і з flex-grow.
