Проблеми плитки на Flexbox
Розглядаємо основні проблеми створення плитки за допомогою Flexbox: необхідність фіксованої висоти контейнера та неправильне розташування елементів у неповному останньому рядку.
Проблема з фіксованою висотою
Для створення вертикальних проміжків між рядами ми використовували align-content: space-between. Але для його роботи контейнеру потрібно мати вільний простір у поперечній осі. Тому в попередньому прикладі ми були змушені явно задавати висоту контейнера.
.parent { display: flex; flex-wrap: wrap; justify-content: space-between; align-content: space-between; width: 320px; height: 320px; }Це незручно, якщо кількість елементів може змінюватися. Наприклад, сьогодні є 9 елементів, завтра 12, а потім 7. Кількість рядів змінюється, а фіксована висота контейнера вже не підходить.
Проблема з неповним останнім рядом
Друга проблема виникає, коли кількість елементів не ділиться на кількість елементів у рядку. Наприклад, якщо потрібно розмістити по три елементи в ряд, а всього є вісім елементів, останній ряд міститиме лише два.
<div class="parent"> <div class="child">1</div> <div class="child">2</div> <div class="child">3</div> <div class="child">4</div> <div class="child">5</div> <div class="child">6</div> <div class="child">7</div> <div class="child">8</div> </div>.parent { display: flex; flex-wrap: wrap; justify-content: space-between; width: 320px; } .child { box-sizing: border-box; width: 100px; height: 100px; border: 1px solid green; }Чому space-between не підходить для такої плитки
justify-content: space-between розподіляє вільний простір між елементами кожного окремого flex-рядка. Він не знає, що ми хочемо зберегти однакові колонки в усіх рядах.
Тому в повному рядку з трьома елементами проміжки можуть бути однаковими, а в неповному рядку з двома елементами простір розподілиться зовсім інакше.
Повний ряд: [100] 20px [100] 20px [100] Неповний ряд із space-between: [100] [100]Коли такий спосіб можна використовувати
Плитка на Flexbox із space-between може бути зручною, якщо кількість елементів відома заздалегідь, кількість елементів у кожному рядку завжди однакова, а висота контейнера не створює проблем.
Якщо ж кількість елементів змінюється динамічно або останній ряд може бути неповним, краще використовувати інший підхід.
Для справжніх сіток із рядками та колонками зазвичай зручніше використовувати CSS Grid. Flexbox більше орієнтований на розподіл елементів уздовж однієї осі, тому створення повноцінної двовимірної плитки на ньому потребує додаткових прийомів.
Практичне завдання №1
- Є 12 елементів.
- Створіть плитку по 4 елементи в ряд.
- Ширина кожного елемента — 100px.
- Відстань між елементами — 20px.
<!-- Початковий код --> <div class="parent"> <div class="child">1</div> <div class="child">2</div> <div class="child">3</div> <div class="child">4</div> <div class="child">5</div> <div class="child">6</div> <div class="child">7</div> <div class="child">8</div> <div class="child">9</div> <div class="child">10</div> <div class="child">11</div> <div class="child">12</div> </div>💡 Показати підказку
Для чотирьох елементів по 100px потрібно 400px. Між ними буде три проміжки по 20px. Ширина контейнера має дорівнювати 460px.
✅ Показати відповідь
.parent { display: flex; flex-wrap: wrap; justify-content: space-between; width: 460px; } .child { box-sizing: border-box; width: 100px; height: 100px; }Практичне завдання №2
- Є 12 елементів.
- Створіть плитку по 3 елементи в ряд.
- Ширина кожного елемента — 150px.
- Відстань між елементами — 10px.
<!-- Початковий код --> <div class="parent"> <div class="child">1</div> <div class="child">2</div> <div class="child">3</div> <div class="child">4</div> <div class="child">5</div> <div class="child">6</div> <div class="child">7</div> <div class="child">8</div> <div class="child">9</div> <div class="child">10</div> <div class="child">11</div> <div class="child">12</div> </div>💡 Показати підказку
Три елементи по 150px займають 450px. Додайте два проміжки по 10px. Отже, ширина контейнера — 470px.
✅ Показати відповідь
.parent { display: flex; flex-wrap: wrap; justify-content: space-between; width: 470px; } .child { box-sizing: border-box; width: 150px; height: 100px; }