Як працює Флексбокс: cистема компонування елементів на веб-сторінці [*]


Дізнайтесь більше про нові кар'єрні можливості в EchoUA. Цікаві проекти, ринкова оплата, гарний колектив. Надсилайте резюме та приєднуйтеся до нас.

Flexbox (Флексбокс) покликаний врятувати нас від неприємних моментів чистого CSS (наприклад, від вертикального вирівнювання), і він відмінно справляється зі своїм завданням. Але розібратися в принципах його роботи іноді буває складно, особливо, якщо ви новачок.

Основне завдання Flexbox – зробити шари (layers) гнучкими, а роботу з ними – інтуїтивно зрозумілими. Для досягнення цієї мети він дозволяє контейнерам самим вирішувати, як поводитися зі своїми дочірніми елементами, у тому числі змінювати їх розмір і відстань між ними.

Звучить непогано, але давайте подивимося, чи так воно буде на практиці. У цій статті ми вивчимо 5 найпопулярніших властивостей Флексбоксу, розберемося, що вони роблять, і як вони насправді працюють.

Display: Flex

Ось приклад сторінки :

У нас є 4 різноколірних div ‘а різних розмірів, які знаходяться усередині сірого div ‘а. У кожного div ‘а є властивість display: block. Тому кожен квадрат займає всю ширину рядка.

Щоб почати працювати з Flexbox, нам треба зробити наш контейнер flex-контейнером. Робиться це так:

#container { display: flex;}

Начебто нічого особливо і не змінилося – div-и всього лише встали в ряд. Але ви зробили щось дійсно потужне. Ви дали вашим квадратам класну властивість, так званий “flex-контекст”.

Flex Direction

У flex-контейнера є дві осі: головна вісь і перпендикулярна їй.

За умовчанням усі предмети розташовуються уздовж головної осі: зліва направо. Тому наші квадрати вирівнялися в лінію, коли ми застосували display: flex. Проте flex-direction дозволяє обертати головну вісь.

#container { display: flex; flex-direction: column;}

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

Є ще пару властивостей для flex-direction: row-reverse і column-reverse.

Justify Content

justify-content відповідає за вирівнювання елементів по головній осі. Повернемося до flex-direction: row.

#container { display: flex; flex-direction: row; justify-content: flex - start;}

justify-content може приймати 5 значень:

  1. flex-start;
  2. flex-end;
  3. center;
  4. space-between;
  5. space-around.

Space-between задає однакову відстань між квадратами, але не між контейнером і квадратами. Space-around також задає однакову відстань між квадратами, але тепер відстань між контейнером і квадратами дорівнює половині відстані між квадратами.

Align Items

Якщо justify-content працює з головною віссю, то align-items працює з віссю, перпендикулярній головній осі.

Повернемося назад до flex-direction: row і пройдемося по командах align-items:

  1. flex-start;
  2. flex-end;
  3. center;
  4. stretch;
  5. baseline.

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

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

Align Self

align-self дозволяє вирівнювати елементи окремо.

#container { align-items: flex - start;}.square#one { align-self: center;}// Only this square will be centered.

Давайте для двох квадратів застосуємо align-self, а для інших застосуємо align-items: center і flex-direction: row.

Flex Basis

flex-basis відповідає за первинний розмір елементів до того, як вони будуть змінені іншими властивостями Флексбокс:

Flex-basis впливає на розмір елементів уздовж головної осі.

Давайте подивимося, що станеться, якщо ми змінимо напрям головної осі :

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

Flex Grow

Ця властивість трохи складніша. Спершу давайте задамо нашим квадратикам однакову ширину в 120px:

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

Квадрати зайняли місце, що залишилося, в контейнері. Значення flex-grow анулює значення ширини. Але тут виникає одне питання: що означає 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-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 замінює 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) стискатиметься в два рази швидше.

Як речі ростуть і стискаються

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

Трохи математики

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

Теж саме відбувається і з flex-grow.

Київ, Харків, Одеса, Дніпро, Запоріжжя, Кривий Ріг, Вінниця, Херсон, Черкаси, Житомир, Хмельницький, Чернівці, Рівне, Івано-Франківськ, Кременчук, Тернопіль, Луцьк, Ужгород, Кам'янець-Подільський, Стрий - за статистикою саме з цих міст програмісти найбільше переїжджають працювати до Львова. А Ви розглядаєте relocate?


Коментарі 1

  • Дійсно, для новачків корисна інформація, я не одну годину витратив сам, коли розбирався з властивостями. Хоча нічого важкого абсолютно немає, багато речей робиться на інтуітивному рівні. Достатньо просто бути уважним і один-два рази попрацювати з флексбоксом – далі це просто на автоматі вже робиш і сами дивуєшся, що тут було такого складного. Але без нормальних пояснень, особливо, коли, як я, розбираєшся в усьому сам, буває насправді нелегко.

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *