Jakie są różnice między podstawą elastyczną a szerokością?

224

Pojawiły się pytania i artykuły na ten temat, ale o ile mogę powiedzieć, nic rozstrzygającego. Najlepsze podsumowanie, jakie mogłem znaleźć, to

Flex-Base pozwala określić początkowy / początkowy rozmiar elementu, zanim cokolwiek innego zostanie obliczone. Może to być wartość procentowa lub bezwzględna.

... co samo w sobie niewiele mówi o zachowaniu elementów z zestawem flex- base . Z moją obecną wiedzą na temat flexboksa nie rozumiem, dlaczego nie mógłbym również opisać szerokości .

Chciałbym wiedzieć, jak dokładnie podstawa flex różni się od szerokości w praktyce:

  • Gdybym zastąpić szerokość z giętkiego podstawie (i odwrotnie), co zmieni się wizualnie?
  • Co się stanie, jeśli ustawię obie na inną wartość? Co się stanie, jeśli będą miały tę samą wartość?
  • Czy są jakieś szczególne przypadki, w których użycie albo szerokości, albo elastycznej podstawy miałoby znaczącą różnicę w porównaniu z drugą?
  • Czym różni się szerokość i podstawa elastyczności w połączeniu z innymi stylami Flexbox, takimi jak flex-wrap , flex-grow i flex-shrink ?
  • Jakieś inne istotne różnice?

Edycja / wyjaśnienie : To pytanie zostało zadane w innym formacie w Co dokładnie w zestawach właściwości flex-base? ale czułem, że bardziej bezpośrednie byłoby porównanie lub podsumowanie różnic w podstawie podstawy i szerokości (lub wysokości ).

jpeltoniemi
źródło
Najlepszy artykuł wyjaśniający podstawy flex, flex rośnie i kurczy się całkowicie
ZenVentzi

Odpowiedzi:

339

Rozważać flex-direction

Pierwszą rzeczą, która przychodzi na myśl podczas czytania pytania, jest to, że flex-basisnie zawsze ma to zastosowanie width.

Kiedy flex-directionjest row, flex-basiskontroluje szerokość.

Ale kiedy flex-directionjest column, flex-basiskontroluje wysokość.


Kluczowe różnice

Oto kilka ważnych różnic między flex-basisi width/ height:

  • flex-basisdotyczy tylko elementów flex. Elastyczne kontenery (które nie są również elastycznymi przedmiotami) będą ignorować, flex-basisale mogą używać widthi height.

  • flex-basisdziała tylko na głównej osi. Na przykład, jeśli jesteś w środku flex-direction: column, widthwłaściwość będzie potrzebna do wymiarowania elastycznych elementów w poziomie.

  • flex-basisnie ma wpływu na absolutnie ustawione elementy elastyczne. widthi heightwłaściwości byłyby konieczne. Absolutnie umieszczone elementy flex nie uczestniczą w układzie flex .

  • Za pomocą flexwłaściwości, trzy właściwości: - flex-grow, flex-shrinki flex-basis- można wygodnie łączy się w jednym zgłoszeniu. Korzystanie z widthtej samej reguły wymagałoby wielu wierszy kodu.


Zachowanie przeglądarki

Pod względem sposobu ich renderowania nie powinno być różnicy między flex-basisi width, chyba że flex-basisjest autolub content.

Ze specyfikacji:

7.2.3 flex-basisnieruchomość

Dla wszystkich wartości innych niż autoa content, flex-basiszostał rozwiązany w ten sam sposób jak widthw poziomym trybie zapisu.

Ale wpływ autolub contentmoże być minimalny lub wcale. Więcej ze specyfikacji:

auto

Po określeniu w elemencie elastycznym autosłowo kluczowe pobiera wartość właściwości rozmiaru głównego jako użytej flex-basis. Jeśli ta wartość jest sama auto, wówczas używana jest wartość content.

content

Wskazuje automatyczną zmianę rozmiaru na podstawie zawartości elementu flex.

Uwaga: ta wartość nie była obecna w początkowej wersji programu Flexible Box Layout, a zatem niektóre starsze implementacje jej nie obsługują. Równoważny efekt można osiągnąć, stosując autorazem z głównym rozmiarem ( widthlub height) wynoszącym auto.

Tak więc, zgodnie ze specyfikacją, flex-basisi widthrozwiązać identycznie, chyba że flex-basisjest autolub content. W takich przypadkach flex-basismoże użyć szerokości treści (która, przypuszczalnie, również widthskorzystałaby z właściwości).


flex-shrinkczynnikiem

Ważne jest, aby pamiętać o początkowych ustawieniach elastycznego pojemnika. Niektóre z tych ustawień obejmują:

  • flex-direction: row - elementy elastyczne zostaną wyrównane w poziomie
  • justify-content: flex-start - elementy elastyczne będą układać się w stos na początku linii na głównej osi
  • align-items: stretch - elementy elastyczne zostaną rozszerzone, aby pokryć pojemnik o przekroju poprzecznym
  • flex-wrap: nowrap - przedmioty elastyczne są zmuszone pozostać w jednej linii
  • flex-shrink: 1 - przedmiot elastyczny może się kurczyć

Zwróć uwagę na ostatnie ustawienie.

Ponieważ elementy elastyczne mogą domyślnie się kurczyć (co zapobiega przepełnieniu kontenera), określone flex-basis/ width/ heightmoże zostać zastąpione.

Na przykład flex-basis: 100pxlub width: 100pxw połączeniu z flex-shrink: 1niekoniecznie będzie to 100 pikseli.

Aby wyrenderować określoną szerokość - i utrzymać ją na stałym poziomie - musisz wyłączyć zmniejszanie:

div {
   width: 100px;
   flex-shrink: 0;
}  

LUB

div {
  flex-basis: 100px;
  flex-shrink: 0;
}

LUB, zgodnie z zaleceniami specyfikacji:

flex: 0 0 100px;    /* don't grow, don't shrink, stay fixed at 100px */

7.2 Składniki elastyczności

Autorzy są zachęcani do kontrolowania elastyczności za pomocą flexstenografii, a nie bezpośrednio z jej właściwościami długodystansowymi, ponieważ stenografia poprawnie resetuje nieokreślone komponenty, aby uwzględnić typowe zastosowania .


Błędy przeglądarki

Niektóre przeglądarki mają problemy ze zmianą wielkości elementów elastycznych w zagnieżdżonych kontenerach elastycznych.

flex-basisignorowane w zagnieżdżonym kontenerze Flex. widthPracuje.

Podczas używania flex-basiskontener ignoruje wielkość jego elementów potomnych, a dzieci przepełniają pojemnik. Ale w przypadku tej widthwłaściwości kontener szanuje wielkość swoich dzieci i odpowiednio się rozszerza.

Bibliografia:

Przykłady:


wyginać przedmioty za pomocą flex-basisi white-space: nowrapprzepełniać inline-flexpojemnik. widthPracuje.

Wygląda na to, że elastyczny zestaw kontenerów inline-flex, którego nie rozpoznaje flex-basisdziecko podczas renderowania rodzeństwa white-space: nowrap(chociaż może to być tylko element o nieokreślonej szerokości). Pojemnik nie rozszerza się, aby pomieścić przedmioty.

Ale gdy widthwłaściwość jest używana zamiast flex-basis, kontener uwzględnia wielkość swoich potomków i odpowiednio się rozszerza. To nie jest problem w IE11 i Edge.

Bibliografia:

Przykład:


flex-basis(i flex-grow) nie działa na elemencie tabeli

Bibliografia:


flex-basiszawodzi w Chrome i Firefoksie, gdy pojemnik dziadka jest elementem kurczącym się, aby dopasować. Konfiguracja działa dobrze w Edge.

Podobnie jak w przykładzie przedstawionym w powyższym odsyłaczu, position: absoluteużycie floati inline-blockspowoduje również wyświetlenie tego samego wadliwego wyniku ( demo jsfiddle ).


Błędy wpływające na IE 10 i 11:

Michael Benjamin
źródło
2
Jak o min-width:100px;? Czy może to być opcja wyłączenia obkurczania?
Mori
1
@Mori, tak, flex-shrinkzatrzymuje się na min-width. Równoważna zasada flex byłaby flex: 1 0 100px.
Michael Benjamin
flex: 1 0 100pxprowadzi do tego samego wyniku, ale nie jestem pewien, co rozumiesz przez „równoważny”.
Mori
Mam na myśli, dlaczego nie powinniśmy uważać, że jest równa flex: 0 0 100px, na przykład?
Mori
2
@Mori, ponieważ wtedy jest równa szerokości . Potrzebuje Flex-Grow: 1 komponent, aby umożliwić wzrost elementu z minimalnej szerokości, ustawionej przez Flex-Base .
Michael Benjamin
33

Oprócz doskonałego podsumowania Michael_B warto to powtórzyć:

Flex-Base pozwala określić początkowy / początkowy rozmiar elementu, zanim cokolwiek innego zostanie obliczone. Może to być wartość procentowa lub bezwzględna.

Ważna część tutaj jest początkowa .

Samo to rozwiązuje problem szerokości / wysokości, dopóki inne właściwości elastycznego wzrostu / kurczenia się nie wejdą w grę.

Więc. dziecko z

.child {
 flex-basis:25%;
 flex-grow:1;
}

będzie początkowo miał szerokość 25%, ale następnie natychmiast rozszerzy tyle, ile może, dopóki nie zostaną uwzględnione pozostałe elementy. Jeśli nie ma, to będzie 100% szerokości / wysokości.

Szybkie demo:

Eksperymentowanie z flex-grow, flex-shrinki flex-basis (lub skrótem flex :fg fs fb) ... może prowadzić do interesujących rezultatów.

Paulie_D
źródło
Okazało się, że na ogół w ramach elastycznego oba flex-basisi width / heightustawić na początku / wielkość wyjściową elementu. Na przykład w flex-basis: 200pxzasadzie działa tak samo jak flex-basis: auto; width: 200px;. Wygląda na to, że kiedy flex-basisnie jest ustawiony, autoto po prostu przesłania width / heightwartość. Jedyną różnicą, którą widzę, jest sposób obsługi przepełnienia zawartości.
Karolis
5

Być może najważniejszy punkt do dodania:

Co jeśli przeglądarka nie obsługuje flex? W takim przypadku width/heightprzejmij i zastosuj ich wartości.

To bardzo dobry pomysł - prawie niezbędny - zdefiniować width/heightna elementach, nawet jeśli masz wtedy zupełnie inną wartość flex-basis. Pamiętaj, aby przetestować, wyłączając display:flexi sprawdzając, co otrzymujesz.

Niet the Dark Absol
źródło
2
Wśród głównych przeglądarek jedynymi, które nie obsługują właściwości flex, są IE <10. caniuse.com/#search=flex
Michael Benjamin
1
@Michael_B Pewnie, a może to tylko ja, ale muszę też obsługiwać przeglądarki mobilne, włącznie z przeglądarką Nintendo 3DS, która zdecydowanie nie obsługuje flex.
Niet the Dark Absol