12.11. Właściwości flex-basis
, flex-grow
, flex-shrink
Kontrolowanie elastyczności elementów flex
Podczas gdy właściwości takie jak justify-content
i align-items
zarządzają wyrównaniem, właściwości flex-basis
, flex-grow
i flex-shrink
kontrolują **rozmiar i elastyczność** poszczególnych elementów flex wzdłuż osi głównej.
Te trzy właściwości są kluczowe dla zrozumienia, jak Flexbox rozdziela przestrzeń i dostosowuje rozmiary elementów.
Stosuje się je bezpośrednio do **elementów flex** (dzieci kontenera), a nie do kontenera.
flex-basis
: Rozmiar początkowy
Właściwość flex-basis
definiuje **początkowy (bazowy) rozmiar** elementu flex wzdłuż osi głównej, **zanim** zostanie zastosowane rozciąganie (flex-grow
) lub kurczenie (flex-shrink
).
- Wartość domyślna:
auto
. W tym przypadku przeglądarka próbuje użyć wartości właściwościwidth
lubheight
elementu (w zależności odflex-direction
). Jeśli one również sąauto
, rozmiar jest określany na podstawie zawartości elementu. - Wartości długości: Można podać konkretną długość (np.
px
,em
,%
). Procenty odnoszą się do rozmiaru kontenera flex wzdłuż osi głównej. content
: (Nowsza wartość) Rozmiar bazowy jest określany na podstawie zawartości elementu, podobnie jak przyauto
, ale z pewnymi niuansami w obliczeniach.
Można myśleć o flex-basis
jak o "sugerowanym" rozmiarze elementu przed rozdzieleniem wolnej przestrzeni.
.item {
flex-basis: 150px; /* Sugerowany rozmiar początkowy to 150px */
}
.item-auto {
flex-basis: auto; /* Użyj width/height lub rozmiaru zawartości */
}
.item-percent {
flex-basis: 25%; /* Sugerowany rozmiar to 25% szerokości kontenera */
}
Uwaga: Jeśli jednocześnie ustawisz flex-basis
(inne niż auto
) oraz width
(przy flex-direction: row
) lub height
(przy flex-direction: column
), to flex-basis
ma pierwszeństwo.
flex-grow
: Zdolność do rozciągania
Właściwość flex-grow
określa, **jaką część dostępnej wolnej przestrzeni** w kontenerze (wzdłuż osi głównej) dany element flex powinien "wchłonąć", jeśli jest taka przestrzeń.
- Wartość domyślna:
0
. Oznacza to, że element domyślnie **nie rośnie**, aby wypełnić wolną przestrzeń. Zachowuje swój rozmiar bazowy (flex-basis
). - Wartości liczbowe (nieujemne): Określają **proporcję**, w jakiej element ma rosnąć w stosunku do innych elementów flex w tej samej linii, które również mają
flex-grow > 0
.
Jak to działa?
- Obliczana jest całkowita wolna przestrzeń w linii flex.
- Sumowane są wartości
flex-grow
wszystkich elementów w linii. - Każdy element z
flex-grow > 0
otrzymuje dodatkową przestrzeń proporcjonalną do jego wartościflex-grow
w stosunku do sumy.
Przykład:
<div class="container" style="width: 600px; display: flex;">
<div class="item item-a">A (grow 1)</div>
<div class="item item-b">B (grow 2)</div>
<div class="item item-c">C (grow 0)</div>
</div>
.item {
flex-basis: 100px; /* Każdy zaczyna od 100px */
height: 50px; margin: 5px; background: lightblue;
}
.item-a { flex-grow: 1; background: lightcoral; }
.item-b { flex-grow: 2; background: lightgreen; }
.item-c { flex-grow: 0; /* Domyślnie, nie rośnie */ }
Załóżmy, że kontener ma 600px. Elementy mają flex-basis: 100px
, więc razem zajmują 300px (plus marginesy, pomińmy je dla uproszczenia). Zostaje 300px wolnej przestrzeni.
Suma flex-grow
= 1 (A) + 2 (B) + 0 (C) = 3.
- Element A dostaje 1/3 wolnej przestrzeni: 300px / 3 = 100px. Jego końcowy rozmiar: 100px (basis) + 100px (grow) = 200px.
- Element B dostaje 2/3 wolnej przestrzeni: (300px / 3) * 2 = 200px. Jego końcowy rozmiar: 100px (basis) + 200px (grow) = 300px.
- Element C ma
flex-grow: 0
, więc nie rośnie. Jego końcowy rozmiar: 100px (basis).
Razem: 200px + 300px + 100px = 600px (cały kontener).
flex-shrink
: Zdolność do kurczenia
Właściwość flex-shrink
określa, **jaką część "nadmiarowej" przestrzeni** (gdy suma flex-basis
elementów przekracza rozmiar kontenera) dany element flex powinien "oddać", aby zmieścić się w kontenerze.
- Wartość domyślna:
1
. Oznacza to, że element domyślnie **może się kurczyć**, jeśli jest to konieczne. - Wartości liczbowe (nieujemne): Określają **proporcję**, w jakiej element ma się kurczyć w stosunku do innych elementów flex w tej samej linii, które również mają
flex-shrink > 0
. Obliczenia są nieco bardziej złożone niż przyflex-grow
, ponieważ uwzględniają równieżflex-basis
elementu (większe elementy kurczą się proporcjonalnie więcej). flex-shrink: 0
: Element **nie będzie się kurczył** poniżej swojegoflex-basis
.
Przykład:
<div class="container" style="width: 400px; display: flex;">
<div class="item item-x">X (shrink 1)</div>
<div class="item item-y">Y (shrink 2)</div>
<div class="item item-z">Z (shrink 0)</div>
</div>
.item {
flex-basis: 200px; /* Każdy chce mieć 200px */
height: 50px; margin: 5px; background: lightblue;
}
.item-x { flex-shrink: 1; /* Domyślnie */ background: lightcoral; }
.item-y { flex-shrink: 2; background: lightgreen; }
.item-z { flex-shrink: 0; background: lightyellow; } /* Nie kurczy się */
Kontener ma 400px. Suma flex-basis
= 200 + 200 + 200 = 600px. Brakuje 200px.
Element Z ma flex-shrink: 0
, więc zachowa swoje 200px.
Pozostałe 400px nadmiaru muszą zostać "odjęte" od X i Y. Obliczenie ważone: (shrink * basis) dla X = 1 * 200 = 200; dla Y = 2 * 200 = 400. Suma ważona = 600.
- X kurczy się o: (200 / 600) * 200px = 66.67px. Końcowy rozmiar: 200 - 66.67 = 133.33px.
- Y kurczy się o: (400 / 600) * 200px = 133.33px. Końcowy rozmiar: 200 - 133.33 = 66.67px.
- Z zachowuje 200px.
Razem: 133.33 + 66.67 + 200 = 400px (cały kontener).
(Dokładne obliczenia mogą być skomplikowane, ale kluczowe jest zrozumienie, że flex-shrink
kontroluje proporcje kurczenia, a flex-shrink: 0
zapobiega kurczeniu.)
Zadania praktyczne
Zadanie 1 (z rozwiązaniem)
Stwórz kontener flex z trzema elementami. Nadaj wszystkim flex-basis: 100px
. Pierwszemu nadaj flex-grow: 1
, drugiemu flex-grow: 2
, a trzeciemu pozostaw domyślne flex-grow: 0
. Obserwuj, jak rozdzielana jest wolna przestrzeń.
Rozwiązanie:
HTML:
<div class="container-task1" style="display: flex; width: 500px; border: 1px solid black;">
<div class="item item-1">1 (grow 1)</div>
<div class="item item-2">2 (grow 2)</div>
<div class="item item-3">3 (grow 0)</div>
</div>
CSS:
.item {
flex-basis: 100px;
flex-shrink: 0; /* Wyłącz kurczenie dla prostszego przykładu */
height: 50px;
margin: 5px;
background-color: #eee;
border: 1px solid #ccc;
}
.item-1 { flex-grow: 1; }
.item-2 { flex-grow: 2; }
.item-3 { flex-grow: 0; }
Efekt: Kontener ma 500px. Suma basis = 300px. Wolna przestrzeń = 200px. Suma grow = 1+2+0 = 3. Element 1 dostanie 1/3 * 200px, Element 2 dostanie 2/3 * 200px, Element 3 nie urośnie. Końcowe szerokości (bez marginesów): ok. 167px, 233px, 100px.
Zadanie 2 (do samodzielnego wykonania)
Stwórz kontener flex o szerokości 300px z trzema elementami. Nadaj wszystkim flex-basis: 150px
. Pierwszemu nadaj flex-shrink: 0
, drugiemu flex-shrink: 1
, a trzeciemu flex-shrink: 2
. Obserwuj, jak elementy się kurczą (lub nie).
Zadanie 3 (do samodzielnego wykonania)
Stwórz typowy układ nagłówka z logo po lewej i nawigacją po prawej. Użyj Flexbox. Nadaj logo flex-grow: 0
i flex-shrink: 0
(aby zachowało swój rozmiar), a kontenerowi nawigacji nadaj flex-grow: 1
, aby wypełnił pozostałą przestrzeń.
FAQ - Najczęściej zadawane pytania
Jakie są domyślne wartości flex-basis
, flex-grow
, flex-shrink
?
Domyślne wartości to: flex-basis: auto
, flex-grow: 0
, flex-shrink: 1
. Oznacza to, że element domyślnie bierze rozmiar z width
/height
lub zawartości, nie rośnie, ale może się kurczyć.
Co oznacza flex-grow: 1
na wszystkich elementach?
Jeśli wszystkie elementy w linii mają flex-grow: 1
, oznacza to, że cała dostępna wolna przestrzeń zostanie równo rozdzielona między nimi.
Kiedy używać flex-basis
zamiast width
/height
?
flex-basis
jest bardziej