Flexbox: Jak duże jest to elastyczne pudełko?
Opublikowany: 2022-03-10To już trzecia część mojej serii na Flexbox. W poprzednich dwóch artykułach przyjrzeliśmy się, co dzieje się, gdy tworzysz kontener flex i badaliśmy wyrównanie, jak działa w Flexbox. Tym razem przyjrzymy się rozmiarowi. Jak kontrolujemy rozmiar naszych elementów elastycznych i jakich wyborów dokonuje przeglądarka, gdy kontroluje rozmiar?
Wstępne wyświetlanie elementów Flex
Jeśli mam zestaw elementów, które mają różne długości zawartości wewnątrz i ustawię ich rodzica na display: flex
, elementy będą wyświetlane jako wiersz i ustawione w linii na początku tej osi. W poniższym przykładzie moje trzy elementy mają niewielką ilość treści i są w stanie wyświetlić zawartość każdego elementu jako nieprzerwaną linię. Na końcu kontenera flex jest miejsce, do którego elementy nie rosną, ponieważ początkowa wartość flex-grow
wynosi 0
, nie rosną .

Jeśli dodam więcej tekstu do tych elementów, w końcu wypełnią one pojemnik, a tekst zacznie się zawijać. Pudełkom przypisywana jest część miejsca w kontenerze, która odpowiada ilości tekstu w każdym polu — element z dłuższym ciągiem tekstu otrzymuje więcej miejsca. Oznacza to, że nie skończymy z wysoką, chudą kolumną z dużą ilością tekstu, gdy następny element drzwi zawiera tylko jedno słowo.

To zachowanie prawdopodobnie będzie ci znajome, jeśli kiedykolwiek korzystałeś z Flexbox, ale być może zastanawiałeś się, jak przeglądarka działa tak, jak wygląda to w wielu nowoczesnych przeglądarkach, a zobaczysz, że wszystkie robią to samo. Wynika to z faktu, że takie szczegóły są dopracowane w specyfikacji, upewniając się, że każdy implementujący Flexbox w nowej przeglądarce lub innym programie użytkownika jest świadomy tego, jak to obliczenie ma działać. Możemy użyć specyfikacji, aby znaleźć te informacje dla siebie.
Specyfikacja wewnętrznego i zewnętrznego rozmiaru CSS
Patrząc na wszystko, co dotyczy rozmiaru w specyfikacji Flexbox, dość szybko odkrywasz, że wiele potrzebnych informacji znajduje się w innej specyfikacji — CSS Intrisnic i Extrinsic Sizing. Dzieje się tak, ponieważ koncepcje rozmiaru, których używamy, nie są unikalne dla Flexbox, w ten sam sposób, w jaki właściwości wyrównania nie są unikalne dla Flexbox. Jednak aby dowiedzieć się, jak te konstrukcje wymiarowania są używane w Flexbox, musisz zajrzeć do specyfikacji Flexbox. Może się wydawać, że skaczesz tam iz powrotem, więc streszczę tutaj kilka kluczowych definicji, których będę używał w dalszej części artykułu.
Preferowany rozmiar
Preferowany rozmiar pudełka to rozmiar określony przez width
lub height
lub logiczne aliasy tych właściwości inline-size
i block-size
. Używając:
.box { width: 500px; }
Lub logiczny alias inline-size
:
.box { inline-size: 500px; }
Stwierdzasz, że chcesz, aby Twoje pole miało 500 pikseli szerokości lub 500 pikseli w kierunku linii.
Minimalna zawartość Rozmiar
Minimalny rozmiar zawartości to najmniejszy rozmiar, jaki może mieć pudełko bez powodowania przepełnienia. Jeśli twoje pudełko zawiera tekst, zostaną wykorzystane wszystkie możliwe możliwości miękkiego pakowania.
maksymalna zawartość Rozmiar
Maksymalny rozmiar zawartości to największy rozmiar, jaki może mieć pudełko, aby pomieścić zawartość. Jeśli pole zawiera tekst bez formatowania, aby je podzielić, zostanie wyświetlony jako jeden długi nieprzerwany ciąg.
Główny rozmiar elementu elastycznego
Główny rozmiar elementu elastycznego to jego rozmiar w głównym wymiarze. Jeśli pracujesz pod rząd — po angielsku — głównym rozmiarem jest szerokość. W kolumnie w języku angielskim głównym rozmiarem jest wzrost.
Elementy mają również minimalny i maksymalny rozmiar główny określony przez ich min-width
lub min-height
w głównym wymiarze.
Wypracowanie rozmiaru elastycznego przedmiotu
Teraz, gdy mamy już zdefiniowane pewne terminy, możemy przyjrzeć się rozmiarom naszych elementów elastycznych. Początkowe wartości właściwości flex
są następujące:
-
flex-grow: 0
-
flex-shrink: 1
-
flex-basis: auto
Podstawa flex-basis
jest tym, od czego oblicza się rozmiar. Jeśli ustawimy flex-basis
na 0
i flex-grow
na 1, to wszystkie nasze pola nie mają początkowej szerokości, więc przestrzeń w kontenerze flex jest dzielona równomiernie, przypisując taką samą ilość miejsca do każdego elementu.
Zobacz Pen Smashing Flexbox Series 3: flex: 1 1 0; autorstwa Rachel Andrew (@rachelandrew) na CodePen.
Natomiast jeśli flex-basis
to auto
i flex-grow: 1
, dystrybuowana jest tylko wolna przestrzeń, biorąc pod uwagę rozmiar treści.
Zobacz Pen Smashing Flexbox Series 3: flex: 1 1 auto krótki tekst autorstwa Rachel Andrew (@rachelandrew) na CodePen.
W sytuacjach, gdy brakuje wolnego miejsca, np. gdy mamy więcej treści, niż mieści się w jednej linii, wtedy nie ma miejsca do dystrybucji.
Zobacz Pen Smashing Flexbox Series 3: flex: 1 1 auto długi tekst autorstwa Rachel Andrew (@rachelandrew) na CodePen.
To pokazuje nam, że ustalenie, co oznacza auto
, jest bardzo ważne, jeśli chcemy wiedzieć, jak Flexbox określa rozmiar naszych pudeł. Naszym punktem wyjścia będzie wartość auto
.
Definiowanie Auto
Kiedy auto jest zdefiniowane jako wartość czegoś w CSS, będzie miało bardzo konkretne znaczenie w tym kontekście, któremu warto się przyjrzeć. Grupa robocza CSS poświęciła dużo czasu na zastanawianie się, co oznacza auto w dowolnym kontekście, jak wyjaśnia ta rozmowa dla redaktora specyfikacji Fantasai.
Informacje o tym, co oznacza auto
, gdy jest używane jako flex-basis
możemy znaleźć w specyfikacji. Określone powyżej terminy powinny pomóc nam przeanalizować to stwierdzenie.
„Kiedy określone w elemencie flex, słowo kluczowe auto pobiera wartość właściwości main size jako użytą `flex-basis`. Jeśli ta wartość sama w sobie jest auto, użyta wartość to „treść”.
Więc jeśli nasza flex-basis
to auto
, Flexbox sprawdza zdefiniowaną właściwość main size. Mielibyśmy główny rozmiar, gdybyśmy nadawali jakiemukolwiek z naszych elementów elastycznych width
. W poniższym przykładzie wszystkie elementy mają szerokość 110 pikseli, więc jest on używany jako główny rozmiar, ponieważ początkowa wartość dla flex-basis to auto.
Zobacz Pen Smashing Flexbox Series 3: elastyczne elementy o szerokości autorstwa Rachel Andrew (@rachelandrew) na CodePen.
Jednak nasz początkowy przykład zawiera elementy, które nie mają szerokości, co oznacza, że ich główny rozmiar to auto
, więc musimy przejść do następnego zdania: „Jeśli ta wartość sama w sobie jest auto, użyta wartość to content
”.

Musimy teraz przyjrzeć się, co specyfikacja mówi o słowie kluczowym content
. Jest to kolejna wartość, której możesz użyć (w obsługiwanych przeglądarkach) dla swojej flex-basis
, na przykład:
.item { flex: 1 1 content; }
Specyfikacja definiuje content
w następujący sposób:
„Wskazuje rozmiar automatyczny na podstawie zawartości elementu elastycznego. (Zazwyczaj jest to odpowiednik maksymalnego rozmiaru zawartości, ale z korektami w celu obsługi współczynników proporcji, wewnętrznych ograniczeń rozmiaru i przepływów ortogonalnych”
W naszym przykładzie, w przypadku elementów elastycznych zawierających tekst, możemy zignorować niektóre bardziej skomplikowane dostosowania i traktować content
jako maksymalny rozmiar zawartości.
To wyjaśnia, dlaczego, gdy w każdym elemencie mamy niewielką ilość tekstu, tekst się nie zawija. Elementy elastyczne są automatycznie dopasowywane do rozmiaru, więc Flexbox sprawdza ich maksymalny rozmiar zawartości, elementy mieszczą się w swoim pojemniku w tym rozmiarze i praca jest wykonana!
Historia na tym się nie kończy, ponieważ gdy dodajemy więcej treści, pudełka nie zachowują maksymalnego rozmiaru zawartości. Gdyby to zrobiły, wyrwałyby się z elastycznego pojemnika i spowodowały przepełnienie. Po napełnieniu pojemnika zawartość zaczyna się zawijać, a przedmioty przybierają różne rozmiary w zależności od zawartości w nich zawartej.
Rozwiązywanie elastycznych długości
W tym momencie specyfikacja staje się dość złożona, jednak kroki, które należy wykonać, są następujące:
Najpierw zsumuj główny rozmiar wszystkich przedmiotów i sprawdź, czy jest on większy lub mniejszy niż dostępna przestrzeń w pojemniku.
Jeśli rozmiar pojemnika jest większy niż całkowity, będziemy dbać o współczynnik flex-grow
, ponieważ mamy przestrzeń do rozwoju.

Jeśli rozmiar pojemnika jest mniejszy niż całkowity, będziemy dbać o współczynnik flex-shrink
, ponieważ musimy się skurczyć.

Zamrażaj wszelkie nieelastyczne elementy, co oznacza, że już możemy zdecydować o rozmiarze dla niektórych elementów. Jeśli używamy flex-grow
, będzie to obejmowało wszystkie elementy, które mają flex-grow: 0
. To jest scenariusz, który mamy, gdy nasze elastyczne elementy mają wolne miejsce w kontenerze. Początkowa wartość flex-grow
wynosi 0, więc osiągają one wielkość taką jak ich maksymalna szerokość, a następnie nie rosną już od swojego głównego rozmiaru.
Jeśli używamy flex-shrink
, to obejmuje to wszystkie elementy z flex-shrink: 0
. Możemy zobaczyć, co stanie się na tym etapie, jeśli nadamy naszemu zestawowi elementów elastycznych współczynnik flex-shrink
równy 0. Elementy zostają zamrożone w stanie max-content
, a zatem nie wyginają się i nie układają, aby zmieścić się w kontenerze.
Zobacz Pen Smashing Flexbox Series 3: flex: 0 0 auto autorstwa Rachel Andrew (@rachelandrew) na CodePen.
W naszym przypadku — przy początkowych wartościach elementów elastycznych — nasze przedmioty mogą się skurczyć. Tak więc kroki są kontynuowane, a algorytm wchodzi w pętlę, w której oblicza, ile miejsca ma przydzielić lub zabrać. W naszym przypadku używamy flex-shrink
, ponieważ całkowity rozmiar naszych przedmiotów jest większy niż pojemnik, więc musimy zabrać miejsce.
Współczynnik flex-shrink
jest mnożony przez wewnętrzny rozmiar podstawowy elementów , w naszym przypadku jest to max-content
. Daje to wartość, dzięki której można zmniejszyć przestrzeń. Jeśli przedmioty usunęłyby miejsce tylko zgodnie ze współczynnikiem flex-shrink
, małe przedmioty mogłyby zasadniczo zniknąć, po usunięciu całej swojej przestrzeni, podczas gdy większy przedmiot nadal ma miejsce do zmniejszenia.
W tej pętli jest dodatkowy krok, aby sprawdzić elementy, które stałyby się mniejsze lub większe niż ich docelowy rozmiar główny, w którym to przypadku element przestaje się powiększać lub zmniejszać. Ponownie, ma to na celu uniknięcie sytuacji, w której niektóre przedmioty stają się małe lub masywne w porównaniu z resztą przedmiotów.
Wszystko to zostało uproszczone pod względem specyfikacji, ponieważ nie patrzyłem na niektóre z bardziej ekstremalnych scenariuszy i ogólnie możesz po prostu dalej myśleć, zakładając, że jesteś szczęśliwy, gdy Flexbox robi swoje i nie interesuje Cię piksel doskonałość. W większości przypadków należy pamiętać o dwóch poniższych faktach.
Jeśli rozwijasz się z pozycji auto
, flex-basis
będzie traktowany jako dowolna szerokość lub wysokość elementu lub max-content
. Przestrzeń zostanie następnie przypisana zgodnie ze współczynnikiem flex-grow
, używając tego rozmiaru jako punktu początkowego.
Jeśli zmniejszasz opcję auto
, flex-basis
będzie traktowany jako dowolna szerokość lub wysokość elementu lub max-content
. Przestrzeń zostanie następnie usunięta zgodnie z rozmiarem flex-basis
-bass pomnożonym przez współczynnik flex-shrink
, a zatem zostanie usunięta proporcjonalnie do maksymalnego rozmiaru zawartości elementów.
Kontrolowanie wzrostu i kurczenia się
Spędziłem większość tego artykułu na opisie, co robi Flexbox, gdy pozostawia się go własnym urządzeniom. Możesz oczywiście sprawować większą kontrolę nad swoimi elementami flex, używając właściwości flex
. Miejmy nadzieję, że będą bardziej przewidywalne dzięki zrozumieniu tego, co dzieje się za kulisami.
Ustawiając własną flex-basis
lub nadając samemu elementowi rozmiar, który jest następnie używany jako flex-basis
, przejmujesz kontrolę od algorytmu, mówiąc Flexboxowi, że chcesz zwiększyć lub zmniejszyć ten konkretny rozmiar. Możesz całkowicie wyłączyć powiększanie lub kurczenie, ustawiając flex-grow
lub flex-shrink
na 0. W tym miejscu jednak warto wykorzystać chęć kontrolowania elementów flex jako czas na sprawdzenie, czy używasz właściwej metody układu. Jeśli próbujesz ustawić elementy elastyczne w dwóch wymiarach, być może lepiej wybierzesz układ siatki.
Problemy związane z rozmiarem debugowania
Jeśli twoje elastyczne elementy mają nieoczekiwany rozmiar, to zazwyczaj dzieje się tak dlatego, że twoja elastyczna podstawa jest automatyczna i jest coś, co nadaje temu elementowi szerokość, która jest następnie używana jako elastyczna podstawa. Sprawdzenie elementu w DevTools może pomóc w określeniu, skąd pochodzi rozmiar. Możesz także spróbować ustawić flex-basis
base na 0
, co zmusi Flexbox do traktowania elementu jako posiadającego zerową szerokość. Nawet jeśli nie jest to wynik, którego oczekujesz, pomoże to zidentyfikować używaną wartość flex-basis
jako winowajcę problemów z rozmiarem.
Luki elastyczne
Bardzo pożądaną funkcją Flexbox jest możliwość określania przerw lub rynien między elementami elastycznymi w taki sam sposób, w jaki możemy określać przerwy w układzie siatki i układzie wielokolumnowym. Ta funkcja jest określona dla Flexbox jako część Box Alignment, a pierwsza implementacja przeglądarki jest w drodze. Firefox spodziewa się dostarczyć właściwości luki dla Flexbox w Firefoksie 63. Poniższy przykład można zobaczyć w Firefox Nightly.
Zobacz Pen Smashing Flexbox Series 3: flex-gaps autorstwa Rachel Andrew (@rachelandrew) na CodePen.

Podobnie jak w przypadku układu siatki, długość odstępu jest brana pod uwagę przed rozmieszczeniem miejsca na elementy elastyczne.
Zawijanie
W tym artykule próbowałem wyjaśnić niektóre z niuansów, w jaki sposób Flexbox określa, jak duże są elementy flex. Może się to wydawać trochę akademickie, jednak poświęcenie trochę czasu na zrozumienie sposobu, w jaki to działa, może zaoszczędzić mnóstwo czasu podczas korzystania z Flexbox w swoich układach. Uważam, że bardzo pomocny jest powrót do faktu, że Flexbox domyślnie stara się zapewnić najbardziej rozsądny układ wielu przedmiotów o różnych rozmiarach. Jeśli element ma więcej treści, otrzymuje więcej miejsca. Jeśli Ty i Twój projekt nie zgadzacie się z tym, co Flexbox uważa za najlepsze, możesz odzyskać kontrolę, ustawiając własną flex-basis
.