Jak sprawić, by Flexbox dzieci miały 100% wzrostu swoich rodziców?

458

Próbuję wypełnić pionową przestrzeń elementu Flex w Flexbox.

.container {
  height: 200px;
  width: 500px;
  display: flex;
  flex-direction: row;
}
.flex-1 {
  width: 100px;
  background-color: blue;
}
.flex-2 {
  position: relative;
  flex: 1;
  background-color: red;
}
.flex-2-child {
  height: 100%;
  width: 100%;
  background-color: green;
}
<div class="container">
  <div class="flex-1"></div>
  <div class="flex-2">
    <div class="flex-2-child"></div>
  </div>
</div>

A oto JSFiddle

flex-2-child nie wypełnia wymaganej wysokości, z wyjątkiem dwóch przypadków, w których:

  1. flex-2 ma wysokość 100% (co jest dziwne, ponieważ element elastyczny ma domyślnie 100% + jest wadliwy w Chrome)
  2. flex-2-child ma pozycję absolutną, co również jest niewygodne

To obecnie nie działa w Chrome ani Firefox.

Raz
źródło
na czym polega problem z użyciem wysokości: 100%; dla .flex-2?
rmagnum2002
Przeciwstawia się celowi elementu elastycznego, który polega na tym, aby wypełnić zawartość samodzielnie i daje mi najdziwniejszy błąd w chromie, w którym wysokość wraca do zera za każdym razem, gdy zmieniam rozmiar okna
Raz
3
W rzeczywistości najnowsza wersja Firefoksa jest jedyną działającą poprawnie
Raz
1
Obecnie istnieją znaczne różnice w zachowaniu między przeglądarkami, jeśli chodzi o renderowanie wysokości procentowych w flexbox: stackoverflow.com/a/35537510/3597276
Michael Benjamin
2
Tak, Chrome ma pewne problemy, szczególnie z zagnieżdżonymi Flexboxami. Na przykład mam zagnieżdżone pudełko z dziećmi, które mają, height:100%ale zamiast tego renderują z naturalną wysokością. Dziwne jest to, że jeśli zmienię ich wysokość na auto, to renderują tak, height:100%jak próbowałem. To zdecydowanie nie jest intuicyjne, jeśli tak powinno działać.
trusktr

Odpowiedzi:

235

Posługiwać się align-items: stretch

Podobnie do odpowiedzi Davida Storeya, moje obejście:

.flex-2 {
    display: flex;
    align-items: stretch;
}

Alternatywnie align-itemsmożesz użyć align-selftylko .flex-2-childprzedmiotu, który chcesz rozciągnąć.

BT
źródło
7
stretch: to powinna być wybrana odpowiedź.
Dave Everitt
1
Zdecydowanie jest to zdecydowanie najlepsza odpowiedź na pytanie. Działa świetnie.
marcias
Tak, to rzeczywiście najlepsza odpowiedź na to pytanie.
Øyvind Bråthen
19
nie zapomnij również usunąć height: 100%z elementu potomnego elementu, który ma mieć taką samą wysokość jak rodzic
Ilham Wahabi GX
Dodaj usunięcie height: 100%do odpowiedzi - prawie się poddałem i widziałem to tylko w ostatniej chwili przed powrotem do absolute- co wiąże się z różnego rodzaju problemami.
Peter
274

Odpowiedziałem na podobne pytanie tutaj .

Wiem, że już powiedziałeś, że position: absolute;jest niewygodny, ale działa. Poniżej znajdują się dalsze informacje dotyczące rozwiązywania problemu zmiany rozmiaru.

Zobacz także jsFiddle, aby zobaczyć wersję demonstracyjną, chociaż dodałem tylko prefiksy webkit, które są tak otwarte w Chrome.

Zasadniczo masz 2 problemy, z którymi osobno się zajmę.

  1. Sprawienie, by dziecko elementu elastycznego wypełniło się na 100%
    • Ustaw position: relative;na rodzic dziecka.
    • Ustaw position: absolute;na dziecko.
    • Następnie możesz ustawić szerokość / wysokość zgodnie z wymaganiami (100% w mojej próbce).
  2. Naprawianie przewijania „dziwactwa” w Chrome
    • Załóż overflow-y: auto;przewijalny div.
    • Przewijalny div musi mieć określoną wyraźną wysokość. Moja próbka ma już wysokość 100%, ale jeśli nie została jeszcze zastosowana, możesz ją określićheight: 0;

Zobacz tę odpowiedź, aby uzyskać więcej informacji na temat przewijania.

Brett Postin
źródło
10
Punkt 1) działa idealnie w przeglądarce Chrome, Firefox nie potrzebuje absolutnej pozycji.
yuri,
223

Jeśli dobrze rozumiem, chcesz, aby flex-2-child wypełnił wysokość i szerokość swojego elementu nadrzędnego, aby czerwony obszar był w pełni pokryty zielonym?

Jeśli tak, wystarczy ustawić flex-2, aby używać Flexbox:

.flex-2 {
    display: flex;  
}

Następnie powiedz flex-2-child, aby stał się elastyczny:

.flex-2-child {    
    flex: 1;
}

Zobacz http://jsfiddle.net/2ZDuE/10/

Powodem jest to, że flex-2-child nie jest elementem Flexbox, ale jego rodzicem jest.

David Storey
źródło
Jak mogę zrobić to samo, tylko przy wzroście 100%, a każde dziecko ma 50/50?
Ricky Levi
7
Pamiętaj, że jeśli użyjesz „align-items: centre”, nie będziesz mógł skorzystać z tej poprawki, ponieważ twoje przedmioty będą teraz miały taką samą wysokość.
Neil Monroe,
10
@NeilMonroe Nadal możesz używać, align-items: centerjeśli używasz align-self: stretchtylko na jedno dziecko.
BT
1
Cześć @David, wypróbowałem twoje rozwiązanie, działa dobrze dla układu flex-direction: układ wierszy, wydaje się, że nie działa z układem flex-direction: układ kolumn, lub mam nieprawidłowe miejsca w kodzie. Czy mógłbyś pomóc sprawdzić, dlaczego w tym skrzypce jsfiddle.net/78o54Lmv wewnętrzna skrzynka nie zajmuje pełnej wysokości swojego rodzica?
huan feng
Muszę dodać min-height: 100vh;do .flex-2elementu, aby działał. Dzięki za pomoc!
Tenaciousd93
24

Przypuszczam, że zachowanie Chrome jest bardziej zgodne ze specyfikacją CSS (choć jest mniej intuicyjne). Zgodnie ze specyfikacją Flexbox domyślna stretchwartość align-selfwłaściwości zmienia tylko wartość użytą „właściwości cross size” elementu ( heightw tym przypadku). I, jak rozumiem specyfikację CSS2.1 , wysokości procentowe są obliczane na podstawie określonej wartości wartości nadrzędnej height, a nie jej wartości użytej. Na określoną wartość rodzica heightnie mają wpływu żadne właściwości flex i nadal jest auto.

Ustawienie wyraźnych height: 100%sprawia, że formalnie można obliczyć wysokość procentową dziecka, podobnie jak ustawienie height: 100%do htmlpozwala obliczyć wysokość procentową bodyw CSS2.1.

Ilya Streltsyn
źródło
2
Dokładnie! Aby zastosować to w praktyce, wystarczy dodać height:100%do .flex-2. Oto jsfiddle .
CourtDemone
7
Zachowanie Chrome jest bardziej spójne z interpretacją specyfikacji CSS przez zespół Chrome . Chociaż można to interpretować w ten sposób, istnieją o wiele lepsze sposoby interpretacji, które nie uwięziłyby nas na tym bazarze, denerwującym i irytującym zachowaniem. Powinni byli to przemyśleć więcej.
WraithKenny
1
@RickDoesburg, to było ponad rok temu, ale uważam, że musiałem zastosować elementy o stałej wysokości. Chciałbym, żeby te przeglądarki razem działały. Naprawdę nie lubię mobilnej przestrzeni.
Jordan
1
Ustawienie podrzędnego pionowego kontenera Flexbox height: 100%daje mi bardzo dziwne wyniki w Chrome. Wygląda na to, że powoduje to ustawienie „określonej wysokości” na całkowitą wysokość kontenera , a nie na wysokość samego elementu, co powoduje niepożądane przewijanie, gdy inne elementy mają obliczone względem niego rozmiary.
Jules
13

Znalazłem rozwiązanie samodzielnie, załóżmy, że masz CSS poniżej:

.parent {
  align-items: center;
  display: flex;
  justify-content: center;
}

.child {
  height: 100%; <- didn't work
}

W takim przypadku ustawienie wysokości 100% nie będzie działać, więc ustawiam margin-bottomregułę na autoprzykład:

.child {
  margin-bottom: auto;
}

a dziecko zostanie wyrównane do najwyższego z rodziców, możesz także użyć align-selfreguły, jeśli wolisz.

.child {
  align-self: flex-start;
}
użytkownik3896501
źródło
Niezły hack, ale problem polega na tym, że jeśli dziecko jest paskiem bocznym i ma kolor tła, margines jest nadal biały.
Boris Burkov
Wspaniałe w tym rozwiązaniu jest to, że wysokość rodzica może być dynamiczna! Poprzednie rozwiązania wymagają, aby rodzic miał ustaloną wysokość. Dzięki za to.
Bribbons
4

Pomysł polegałby na tym, że display:flex;z flex-direction: row;jest wypełnianiem containerdiv za pomocą .flex-1i .flex-2, ale to nie znaczy, że .flex-2ma wartość domyślną, height:100%;nawet jeśli jest rozciągnięta do pełnej wysokości i aby mieć element potomny ( .flex-2-child) z height:100%;, musisz ustawić nadrzędnego height:100%;lub użyć display:flex;z flex-direction: row;na .flex-2div też.

Z tego, co wiem display:flex, nie zwiększy wysokości wszystkich elementów dziecka do 100%.

Małe demo, usunięto wysokość .flex-2-childi zastosowano display:flex;na .flex-2: http://jsfiddle.net/2ZDuE/3/

rmagnum2002
źródło
3

HTML

<div class="container">
    <div class="flex-1"></div>
    <div class="flex-2">
        <div class="flex-2-child"></div>
    </div>
</div>

css

.container {
    height: 200px;
    width: 500px;
    display: -moz-box;
    display: -webkit-flexbox;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: -moz-flex;
    display: flex;
    -webkit-flex-direction: row;
    -moz-flex-direction: row;
    -ms-flex-direction: row;
    flex-direction: row;
}
.flex-1 {
   flex:1 0 100px;
    background-color: blue;
}
.flex-2 {
    -moz-box-flex: 1;
    -webkit-flex: 1;
    -moz-flex: 1;
    -ms-flex: 1;
    flex: 1 0 100%;
    background-color: red;
}
.flex-2-child {
    flex: 1 0 100%;
    height:100%;
    background-color: green;
}

http://jsfiddle.net/2ZDuE/750/

Carol McKay
źródło
0

Można to również rozwiązać za align-self: stretch;pomocą elementu, który chcemy rozciągnąć.

Czasami pożądane jest rozciągnięcie tylko jednego elementu w konfiguracji Flexbox.

.container {
  height: 200px;
  width: 500px;
  display: flex;
  flex-direction: row;
}
.flex-1 {
  width: 100px;
  background-color: blue;
}
.flex-2 {
  position: relative;
  flex: 1;
  align-self: stretch;
  background-color: red;
}
.flex-2-child {
  background-color: green;
}
<div class="container">
  <div class="flex-1"></div>
  <div class="flex-2">
    <div class="flex-2-child"></div>
  </div>
</div>

GiorgosK
źródło
-7

.pojemnik { . . . . wyrównaj elementy: odcinek; . . . . }

HRK
źródło
5
Witamy w Stackoverflow. Musisz w pełni wyjaśnić swoją odpowiedź, a jej wkład różni się od istniejących odpowiedzi. Zobacz stackoverflow.com/help/how-to-answer
Simon.SA
1
Twoja odpowiedź wydaje się być taka sama jak BT (napisana ponad trzy lata wcześniej), ale jest znacznie gorsza.
Quentin,
-12

To jest moje rozwiązanie za pomocą css +

Przede wszystkim, jeśli pierwsze dziecko (flex-1) powinno mieć 100 pikseli, nie powinno być flex. W css + w rzeczywistości możesz ustawić elastyczne i / lub statyczne elementy (kolumny lub wiersze), a twój przykład stanie się tak prosty:

<div class="container">
  <div class="EXTENDER">
    <div class="COLS">
      <div class="CELL _100px" style="background-color:blue">100px</div>
      <div class="CELL _FLEX" style="background-color:red">flex</div>
    </div>
  </div>
</div>

kontener css:

.container {
    height: 200px;
    width: 500px;
    position:relative;
}

i oczywiście obejmują rdzeń css + 0,2

usłyszeć skrzypce

Marco Allori
źródło