Flexbox: Jak duże jest to elastyczne pudełko?

Opublikowany: 2022-03-10
Szybkie podsumowanie ↬ W ostatnich dwóch artykułach przyjrzeliśmy się, co dzieje się, gdy tworzymy kontener flex, a także przyjrzeliśmy się wyrównaniu. Tym razem zajmiemy się często mylącą kwestią rozmiaru we Flexboxie. W jaki sposób Flexbox decyduje o tym, jak duże powinny być rzeczy?

To 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ą .

Trzy przedmioty z miejscem na końcu
Elementy elastyczne mają miejsce, aby każdy z nich był wyświetlany w jednym wierszu (duży podgląd)

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.

Trzy pozycje, ostatnia pozycja ma dłuższy tekst, a tekst zawija się
Przestrzeń jest rozdzielona, ​​aby dać więcej miejsca na dłuższy przedmiot (duży podgląd)

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.

Więcej po skoku! Kontynuuj czytanie poniżej ↓

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.

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.

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.

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.

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.

elastyczne przedmioty z wolnym miejscem na końcu
W pierwszym przypadku nasze przedmioty mają dostępną przestrzeń do rozwoju. (duży podgląd)

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

elastyczne przedmioty przepełniające pojemnik
W drugim przypadku nasze przedmioty są zbyt duże i muszą się skurczyć, aby zmieściły się w pojemniku. (duży podgląd)

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.

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.

Zobacz Pen Smashing Flexbox Series 3: flex-gaps autorstwa Rachel Andrew (@rachelandrew) na CodePen.
Trzy rzędy przedmiotów z odstępami między rynnami
Obraz widoczny w Firefoksie 63 (duży podgląd)

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 .