Como posso tornar os filhos do Flexbox com 100% de altura dos pais?

459

Estou tentando preencher o espaço vertical de um item flexível dentro de um 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>

E aqui está o JSFiddle

flex-2-child não preenche a altura necessária, exceto nos dois casos em que:

  1. flex-2 tem uma altura de 100% (o que é estranho, porque um item flexível tem 100% por padrão + é defeituoso no Chrome)
  2. flex-2-child tem uma posição absoluta que também é inconveniente

No momento, isso não funciona no Chrome ou Firefox.

Raz
fonte
qual é o problema do uso da altura: 100%; para .flex-2?
rmagnum2002
Ele desafia o propósito do item flexível que é para preencher o conteúdo por si só e ele está me dando o erro mais estranha em cromo onde a altura remonta a zero sempre que eu redimensionar a janela
Raz
3
Na verdade, a versão mais recente do Firefox é a única que está funcionando corretamente.
Raz
1
Atualmente, existem diferenças significativas no comportamento entre os navegadores quando se trata de alturas percentuais renderização em flexbox: stackoverflow.com/a/35537510/3597276
Michael Benjamin
2
Sim, o Chrome tem alguns problemas, especialmente com caixas flexíveis aninhadas. Por exemplo, eu tenho uma caixa flexível aninhada com filhos que têm, height:100%mas eles são renderizados com altura natural. E o mais estranho é que se eu mudar a altura deles auto, eles se renderão height:100%como se eu estivesse tentando fazer. Definitivamente, não é intuitivo se é assim que deve funcionar.
trusktr 25/09

Respostas:

237

Usar align-items: stretch

Semelhante à resposta de David Storey, minha solução alternativa é:

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

Como alternativa align-items, você pode usar align-selfapenas o .flex-2-childitem que deseja esticar.

BT
fonte
7
stretch: esta deve ser a resposta escolhida.
Dave Everitt
1
Definitivamente, essa é de longe a melhor resposta para a pergunta. Funciona perfeitamente.
Marcias
Sim, esta é realmente a melhor resposta para esta pergunta.
Øyvind Bråthen
20
não se esqueça de remover também height: 100%do componente filho que você deseja a mesma altura que o pai
Ilham Wahabi GX 09/01
Por favor, adicione a remoção height: 100%à resposta - eu quase desisti e só vi isso no último momento antes de voltar para absolute-, que vem com todos os tipos de problemas.
Peter
274

Eu respondi uma pergunta semelhante aqui .

Eu sei que você já disse que position: absolute;é inconveniente, mas funciona. Veja abaixo mais informações sobre como corrigir o problema de redimensionamento.

Veja também este jsFiddle para obter uma demonstração, embora eu tenha adicionado apenas prefixos de kit da web tão abertos no Chrome.

Você basicamente tem 2 questões que tratarei separadamente.

  1. Conseguir que o filho de um item flexível preencha a altura 100%
    • Defina position: relative;no pai da criança.
    • Situado position: absolute;na criança.
    • Você pode definir a largura / altura conforme necessário (100% na minha amostra).
  2. Corrigindo a rolagem de redimensionamento "peculiaridade" no Chrome
    • Coloque overflow-y: auto;a div rolável.
    • A div rolável deve ter uma altura explícita especificada. Minha amostra já tem altura 100%, mas se nenhuma já estiver aplicada, você pode especificarheight: 0;

Consulte esta resposta para obter mais informações sobre a questão da rolagem.

Brett Postin
fonte
10
Ponto 1) funciona perfeitamente no Chrome, o Firefox não precisa da posição absoluta.
yuri
223

Se bem entendi, você deseja que o flex-2-child preencha a altura e a largura de seu pai, para que a área vermelha seja totalmente coberta pelo verde?

Nesse caso, você só precisa configurar o flex-2 para usar o flexbox:

.flex-2 {
    display: flex;  
}

Em seguida, diga ao flex-2-child para se tornar flexível:

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

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

O motivo é que flex-2-child não é um item do flexbox, mas seu pai é.

David Storey
fonte
Como posso fazer o mesmo, apenas com uma altura de 100% e cada criança tem 50/50?
Ricky Levi
7
Esteja ciente de que se você usar "align-items: center", não poderá usar essa correção, pois seus itens agora terão a mesma altura.
Neil Monroe
10
@NeilMonroe Você ainda pode usar align-items: centerse usar align-self: stretchapenas uma criança.
BT
1
Oi @ David, eu tentei sua solução, ele funciona bem para o layout de linha flex-direction: row, parece que não está funcionando com flex-direction: layout de coluna, ou eu tenho algum lugar errado no código. Você poderia ajudar a verificar por que, neste violino jsfiddle.net/78o54Lmv , a caixa interna não ocupa toda a altura de seu pai?
huan feng
Eu tenho que adicionar min-height: 100vh;ao .flex-2elemento para fazê-lo funcionar. Obrigado pela ajuda!
Tenaciousd93
24

Suponho que o comportamento do Chrome seja mais consistente com a especificação CSS (embora seja menos intuitivo). De acordo com as especificações do Flexbox, o stretchvalor padrão da align-selfpropriedade altera apenas o valor usado da "propriedade de tamanho cruzado" do elemento ( heightneste caso). E, como eu entendo a especificação CSS2.1 , as alturas de porcentagem são calculadas a partir do valor especificado do pai height, não do valor usado. O valor especificado dos pais heightnão é afetado por nenhuma propriedade flex e ainda é auto.

Definir explícito height: 100%torna formalmente possível calcular a altura percentual da criança, assim como definir height: 100%para htmltorna possível calcular a altura percentual bodyno CSS2.1.

Ilya Streltsyn
fonte
2
Exatamente! Para colocar isso em prática, basta adicionar height:100%a .flex-2. Aqui está o jsfiddle .
precisa saber é o seguinte
7
O comportamento do Chrome é mais consistente com a interpretação da equipe do Chrome das especificações CSS. Embora possa ser interpretado dessa maneira, existem maneiras muito melhores de interpretá-lo, qualquer uma das quais não teria nos aprisionado nesse bazar, comportamento irritante e irritante. Eles deveriam ter pensado mais sobre isso.
WraithKenny
1
@ RickDoesburg, isso foi há mais de um ano, mas acredito que precisei recorrer a elementos de altura fixa. Eu gostaria que esses navegadores se unissem. Estou realmente começando a não gostar do espaço móvel.
Jordan
1
Definir um filho de um contêiner flexbox vertical height: 100%está fornecendo resultados muito estranhos para mim no Chrome. Parece que isso faz com que a "altura especificada" seja definida como a altura total do contêiner , em vez da altura do próprio elemento, causando rolagem indesejada quando outros elementos têm tamanhos calculados em relação a ele.
Jules
13

Encontrei a solução sozinho, suponha que você tenha o CSS abaixo:

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

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

Nesse caso, definir a altura 100% não funcionará; portanto, o que faço é definir a margin-bottomregra para auto, como:

.child {
  margin-bottom: auto;
}

e o filho estiver alinhado com a parte superior do pai, você também pode usar a align-selfregra de qualquer maneira, se preferir.

.child {
  align-self: flex-start;
}
user3896501
fonte
Um truque agradável, mas o problema é: se a criança for uma barra lateral e tiver uma cor de fundo, o espaço da margem ainda será branco.
Boris Burkov 07/07/19
O que é ótimo nessa solução é que a altura dos pais pode ser dinâmica! As soluções anteriores exigem que o pai tenha uma altura definida. Obrigado por isso.
Bribbons 17/03
4

Uma idéia seria que display:flex;com flex-direction: row;está preenchendo a containerdiv com .flex-1e.flex-2 , mas isso não significa que ela .flex-2tenha um padrão, height:100%;mesmo que ela seja estendida até a altura máxima e tenha um elemento filho ( .flex-2-child) com o height:100%;qual você precisará definir o pai height:100%;ou usar display:flex;com flex-direction: row;no .flex-2div também.

Pelo que sei display:flex, não estenderá a altura de todos os elementos filhos para 100%.

Uma pequena demonstração, removida a altura .flex-2-childe usada display:flex;em.flex-2 : http://jsfiddle.net/2ZDuE/3/

rmagnum2002
fonte
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
fonte
0

Isso também pode ser resolvido com align-self: stretch;o elemento que queremos ser esticado.

Às vezes, é desejável esticar apenas um item em uma configuração do 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
fonte
-7

.container {. . . . alinhar itens: alongar; . . . . }

HRK
fonte
5
Bem-vindo ao stackoverflow. Você precisa explicar completamente sua resposta, e o que ela contribui é diferente das respostas existentes. Veja stackoverflow.com/help/how-to-answer
Simon.SA
1
Sua resposta parece ser a mesma da BT (escrita três anos antes), mas expressa muito mais mal.
Quentin
-12

Esta é a minha solução usando css +

Antes de tudo, se o primeiro filho (flex-1) deve ter 100px, não deve ser flex. De fato, no css + você pode definir elementos flexíveis e / ou estáticos (colunas ou linhas) e seu exemplo se torna tão fácil quanto isto:

<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>

CSS do contêiner:

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

e obviamente inclui css + 0.2 core

ouvir o violino

Marco Allori
fonte