Witaj w Bibliotece Aleksandryjskiej Flexbox! Podobnie jak starożytni bibliotekarze musieli precyzyjnie rozmieszczać zwoje na półkach, tak my musimy precyzyjnie kontrolować rozmiar elementów flex. Poznaj trzy najpotężniejsze właściwości: flex-grow, flex-shrink i flex-basis.
flex-basis określa początkowy (bazowy) rozmiar elementu PRZED dystrybucją wolnej przestrzeni.1.item {
2 flex-basis: 200px; /* Początkowy rozmiar 200px */
3}
4
5.item {
6 flex-basis: 0; /* Ignoruj rozmiar treści, zacznij od 0 */
7}
8
9.item {
10 flex-basis: auto; /* Użyj rozmiaru treści (default) */
11}
12
13.item {
14 flex-basis: 50%; /* 50% kontenera */
15}Różnica między width a flex-basis:
1/* Width jest sztywny */
2.item {
3 width: 200px; /* Zawsze 200px */
4}
5
6/* Flex-basis jest sugestią */
7.item {
8 flex-basis: 200px; /* Około 200px, ale może rosnąć/kurczyć się */
9}Analogia egipska: Flex-basis to jak początkowy rozmiar bloku kamiennego przed rzeźbieniem - może zostać powiększony lub pomniejszony w zależności od potrzeb.
flex-grow określa jak bardzo element może rosnąć w stosunku do innych elementów, gdy jest wolna przestrzeń.1.container {
2 display: flex;
3 width: 600px;
4}
5
6.item-1 {
7 flex-grow: 1; /* Zajmie 1 część wolnej przestrzeni */
8 flex-basis: 100px;
9}
10
11.item-2 {
12 flex-grow: 2; /* Zajmie 2 części wolnej przestrzeni */
13 flex-basis: 100px;
14}
15
16.item-3 {
17 flex-grow: 1; /* Zajmie 1 część wolnej przestrzeni */
18 flex-basis: 100px;
19}
20
21/* Wolna przestrzeń: 600px - 300px = 300px
22 Suma flex-grow: 1 + 2 + 1 = 4
23
24 item-1: 100px + (300px × 1/4) = 175px
25 item-2: 100px + (300px × 2/4) = 250px
26 item-3: 100px + (300px × 1/4) = 175px
27*/Wartości:
flex-grow: 0 - element NIE rośnie (default)flex-grow: 1 - element rośnie proporcjonalnieflex-grow: 2 - element rośnie 2x szybciej niż elementy z flex-grow: 1Praktyczny przykład - layout z sidebar:
1.layout {
2 display: flex;
3}
4
5.sidebar {
6 flex-grow: 0; /* Sidebar NIE rośnie */
7 flex-basis: 250px; /* Sztywny rozmiar 250px */
8}
9
10.main-content {
11 flex-grow: 1; /* Main content zajmie całą pozostałą przestrzeń */
12}
13
14.aside {
15 flex-grow: 0; /* Aside NIE rośnie */
16 flex-basis: 200px;
17}flex-shrink określa jak bardzo element może się kurczyć w stosunku do innych, gdy brakuje przestrzeni.1.item {
2 flex-shrink: 1; /* Element może się kurczyć (default) */
3}
4
5.item-important {
6 flex-shrink: 0; /* Element NIE kurczy się */
7}
8
9.item-flexible {
10 flex-shrink: 3; /* Element kurczy się 3x szybciej niż inne */
11}Przykład - zachowanie przy małej przestrzeni:
1.container {
2 display: flex;
3 width: 400px;
4}
5
6.item-1 {
7 flex-basis: 200px;
8 flex-shrink: 1; /* Kurczy się normalnie */
9}
10
11.item-2 {
12 flex-basis: 200px;
13 flex-shrink: 2; /* Kurczy się 2x szybciej */
14}
15
16.item-3 {
17 flex-basis: 200px;
18 flex-shrink: 0; /* NIE kurczy się */
19}
20
21/* Razem: 600px, ale kontener ma tylko 400px
22 Brakuje: 200px
23
24 item-3 pozostanie 200px (flex-shrink: 0)
25 item-1 i item-2 podzielą się kurczeniem proporcjonalnie
26*/Praktyczne użycie - ochrona ważnych elementów:
1.header-logo {
2 flex-shrink: 0; /* Logo NIGDY się nie kurczy */
3 width: 150px;
4}
5
6.header-nav {
7 flex-shrink: 1; /* Nawigacja może się kurczyć */
8}
9
10.header-search {
11 flex-shrink: 2; /* Wyszukiwarka kurczy się najszybciej */
12}Właściwość
flex to skrót dla flex-grow, flex-shrink i flex-basis:1/* flex: grow shrink basis */
2.item {
3 flex: 1 1 200px;
4 /* flex-grow: 1, flex-shrink: 1, flex-basis: 200px */
5}1/* flex: 1 - elastyczny element */
2.item {
3 flex: 1;
4 /* Równoważne: flex: 1 1 0 */
5 /* Rosnij, kurczaj się, zacznij od 0 */
6}
7
8/* flex: auto - naturalny rozmiar z elastycznością */
9.item {
10 flex: auto;
11 /* Równoważne: flex: 1 1 auto */
12 /* Rosnij, kurczaj się, zacznij od rozmiaru treści */
13}
14
15/* flex: none - sztywny rozmiar */
16.item {
17 flex: none;
18 /* Równoważne: flex: 0 0 auto */
19 /* NIE rosnij, NIE kurczaj się */
20}
21
22/* flex: 0 0 200px - absolutnie sztywny */
23.item {
24 flex: 0 0 200px;
25 /* Zawsze 200px, bez rosnięcia/kurczenia */
26}
27
28/* flex: 2 - rośnij 2x szybciej */
29.item {
30 flex: 2;
31 /* Równoważne: flex: 2 1 0 */
32}1<div class="dashboard">
2 <aside class="sidebar">Sidebar (stały)</aside>
3 <main class="main-content">Main (elastyczny)</main>
4 <aside class="widgets">Widgets (stały)</aside>
5</div>1.dashboard {
2 display: flex;
3 gap: 20px;
4 height: 100vh;
5}
6
7.sidebar {
8 flex: 0 0 250px; /* Sztywny: 250px */
9 background: #34495e;
10}
11
12.main-content {
13 flex: 1; /* Zajmie całą pozostałą przestrzeń */
14 background: white;
15 overflow-y: auto;
16}
17
18.widgets {
19 flex: 0 1 300px; /* Preferowany: 300px, może się kurczyć */
20 background: #ecf0f1;
21}
22
23/* Na małych ekranach */
24@media (max-width: 768px) {
25 .dashboard {
26 flex-direction: column;
27 }
28
29 .sidebar,
30 .widgets {
31 flex: 0 0 auto; /* Automatyczny rozmiar */
32 }
33}1<header class="header">
2 <div class="logo">Logo</div>
3 <nav class="nav">Nawigacja</nav>
4 <div class="search">Wyszukiwarka</div>
5 <div class="user">User</div>
6</header>1.header {
2 display: flex;
3 gap: 20px;
4 padding: 10px 20px;
5 background: #2c3e50;
6 align-items: center;
7}
8
9.logo {
10 flex: 0 0 150px; /* Zawsze 150px */
11}
12
13.nav {
14 flex: 1 1 auto; /* Zajmie dostępną przestrzeń */
15 min-width: 0; /* Ważne dla kurczenia się */
16}
17
18.search {
19 flex: 0 1 300px; /* Preferuje 300px, może się kurczyć */
20 min-width: 150px; /* Minimum 150px */
21}
22
23.user {
24 flex: 0 0 100px; /* Zawsze 100px */
25}1<div class="card-grid">
2 <div class="card small">Small</div>
3 <div class="card medium">Medium</div>
4 <div class="card large">Large</div>
5 <div class="card small">Small</div>
6</div>1.card-grid {
2 display: flex;
3 flex-wrap: wrap;
4 gap: 20px;
5}
6
7.card {
8 height: 200px;
9 background: #3498db;
10 color: white;
11 display: flex;
12 align-items: center;
13 justify-content: center;
14}
15
16.card.small {
17 flex: 0 0 calc(25% - 15px); /* 1/4 szerokości minus gap */
18}
19
20.card.medium {
21 flex: 0 0 calc(50% - 10px); /* 1/2 szerokości minus gap */
22}
23
24.card.large {
25 flex: 0 0 100%; /* Pełna szerokość */
26}
27
28@media (max-width: 768px) {
29 .card.small,
30 .card.medium {
31 flex: 0 0 100%; /* Pełna szerokość na mobile */
32 }
33}Problem 1: Element nie rośnie
1/* ❌ Problem */
2.item {
3 flex-grow: 1;
4 width: 200px; /* Width blokuje rosnięcie! */
5}
6
7/* ✅ Rozwiązanie */
8.item {
9 flex: 1; /* flex automatycznie nadpisuje width */
10 /* lub */
11 flex-grow: 1;
12 min-width: 200px; /* Użyj min-width zamiast width */
13}Problem 2: Element nie kurczy się
1/* ❌ Problem */
2.item {
3 flex-shrink: 1;
4 min-width: 300px; /* min-width zapobiega kurczeniu! */
5}
6
7/* ✅ Rozwiązanie */
8.item {
9 flex-shrink: 1;
10 min-width: 0; /* Pozwól na kurczenie */
11}Problem 3: Tekst przepełnia kontener
1/* ❌ Problem */
2.item {
3 flex: 1;
4 /* Długi tekst może wypchnąć element poza kontener */
5}
6
7/* ✅ Rozwiązanie */
8.item {
9 flex: 1;
10 min-width: 0; /* Kluczowe! */
11 overflow: hidden;
12 text-overflow: ellipsis;
13 white-space: nowrap;
14}flex-basis:
flex-grow:
flex-shrink:
flex shorthand:
flex: 1 = elastyczny, zaczyna od 0flex: auto = elastyczny, zaczyna od rozmiaru treściflex: none = sztywny rozmiarflex: 0 0 200px = zawsze 200pxPamiętaj: Flex-grow, flex-shrink i flex-basis to jak rozkazy faraona dla budowniczych piramid - precyzyjnie określają, które bloki mają być większe, które mniejsze, a które muszą pozostać niezmienione!