Gostaria de entender por que a div verde com borda ciano se comporta dessa maneira nesses casos.
Sem embalagem extra:
.wrapper {
display: flex;
border: solid 2px black;
}
.red {
width: 25px;
height: 25px;
background-color: red;
}
.green {
height: 100%;
background-color: green;
border: solid 2px cyan;
}
.blue {
width: 50px;
height: 50px;
background-color: blue;
}
<div class="wrapper">
<div class="red"></div>
<div class="green"></div>
<div class="blue"></div>
</div>
Resultado: a div verde tem altura zero em vez da altura da azul.
Com invólucro extra. Ambos com display flex:
.wrapper {
display: flex;
border: solid 2px black;
}
.red {
width: 25px;
height: 25px;
background-color: red;
}
.green {
height: 100%;
background-color: green;
border: solid 2px cyan;
}
.blue {
width: 50px;
height: 50px;
background-color: blue;
}
<div class="wrapper">
<div class="wrapper">
<div class="red"></div>
<div class="green"></div>
<div class="blue"></div>
</div>
</div>
Resultado: a div verde tem a altura da azul, como esperado.
Com invólucro extra. Apenas o avô com display flex:
.wrapper {
display: flex;
border: solid 2px black;
}
.red {
width: 25px;
height: 25px;
background-color: red;
}
.green {
height: 100%;
background-color: green;
border: solid 2px cyan;
}
.blue {
width: 50px;
height: 50px;
background-color: blue;
}
<div class="wrapper">
<div>
<div class="red"></div>
<div class="green"></div>
<div class="blue"></div>
</div>
</div>
Resultado: a div verde tem altura azul + vermelha + (borda ciano * 2), como esperado.
Por que preciso adicionar um wrapper com display flex para que a porcentagem de altura funcione da maneira que espero?
EDITAR
Fazendo alguns ajustes, descobri algo. No primeiro exemplo, remover height: 100%
(ou definir como auto) faz com que ele cresça. Por que é que quando o div verde tem altura auto ele pega toda a altura do pai (menos sua própria borda), mas não quando é definido como 100% ?
.wrapper {
display: flex;
border: solid 2px black;
}
.red {
width: 25px;
height: 25px;
background-color: red;
}
.green {
height: auto;
background-color: green;
border: solid 2px cyan;
}
.blue {
width: 50px;
height: 50px;
background-color: blue;
}
<div class="wrapper">
<div class="red"></div>
<div class="green"></div>
<div class="blue"></div>
</div>
Primeiro exemplo (sem wrapper extra)
O div verde com
height: '100%'
é definido para ter a mesma altura com seu bloco de contenção, que é o div pai comdisplay: 'flex'
. No entanto, a altura do div pai é indefinida, então eleheight: '100%'
se comportará comoheight: 'auto'
. E não há conteúdo no div verde, então ele terá altura zero.Padrões CSS W3C: altura - porcentagem
Padrões CSS W3C: bloco de contenção
Padrões CSS W3C: tamanho definido e indefinido
Segundo exemplo (com wrapper extra. Ambos com display flex)
O bloco que contém o div verde ainda é seu div pai com
display: 'flex'
, também o wrapper extra. Aqui está uma diferença, o wrapper tem um pai comdisplay: 'flex'
, o que significa que o wrapper é um item flex agora . De acordo com o algoritmo de layout flex, o tamanho do wrapper será considerado definido . Agora 100% será efetivo, faça o div verde ter a mesma altura do wrapper.Descarte alguns detalhes, o procedimento de layout é assim:
25px
.height: '100%'
, mas a altura do bloco que o contém é indefinida agora, então trate comoheight: 'auto'
, o que dá altura de conteúdo 0 + borda * 2. O verde tem altura4px
.50px
.50px
.50px
.50px
. Então as alturas dos seus filhos são definidas como50px
e definidas.25px
e50px
.50px
. A altura total será adicionada border * 2,54px
.Padrões CSS W3C: algoritmo de layout flexível - Tamanhos Definidos
Padrões CSS W3C: algoritmo de layout flexível - Determinação de tamanho cruzado
Terceiro exemplo (com invólucro extra. Apenas o avô com flex de exibição)
O procedimento é similar ao segundo exemplo. As diferenças estão em negrito e itálico.
25px
.height: '100%'
, mas a altura do bloco que o contém é indefinida agora, então trate comoheight: 'auto'
, o que dá altura de conteúdo 0 + borda * 2. O verde tem altura4px
.50px
.79px
.79px
.79px
. Então as alturas dos seus filhos são definidas como79px
e definidas.25px
e50px
.79px
. A altura total será adicionada border * 2,83px
.POR FALAR NISSO
box-sizing: 'border-box'
para evitar o incômodo de adicionar largura de linha de borda.height
do verde do primeiro exemplo. O Flex Layout temalign-items: stretch
por padrão, o que esticará a altura do verde para alinhar o mais alto em sua linha cruzada. Caso contrário, a altura explícita substituirá o alongamento.