html - froggy - La altura no es correcta en los artículos de Flexbox en Chrome
flexbox guia (4)
Esta pregunta ya tiene una respuesta aquí:
Tengo un problema delicado para cualquier gurú de CSS que haya. Mi div verde tiene una altura flexible, ocupando el resto. Y ahora quiero poner un div dentro de ese div que debería ser la mitad del div verde. Pero parece que Chrome lo trata como la mitad de toda la página en lugar del elemento flexible.
http://jsfiddle.net/unh5rw9t/1/
HTML
<body>
<div id="wrapper">
<div id="menu">
1
</div>
<div id="content">2
<div id="half_of_content">2.1</div>
</div>
<div id="footer" style="">
3
</div>
</div>
</body>
CSS
html,body {
height: 100%;
margin: 0;
}
#wrapper {
display: flex;
flex-flow: column;
height: 100%;
}
#menu {
height: 70px;
background-color: purple
}
#content {
flex: 1;
height: 100%;
background-color: green;
}
#half_of_content {
height: 50%;
background-color: yellow;
}
#footer {
height: 100px;
background-color: cyan
}
Fijar:
en #content
establecido
display: flex;
flex-flow: column nowrap;
justify-content: flex-end
en #half_of_content
set flex: 0 0 50%
;
Advertencia: necesitas agregar un div extra
como elemento secundario de #content
.
Aquí está el ejemplo completo:
html,body {
height: 100%;
margin: 0;
}
#wrapper {
display: flex;
flex-flow: column;
height: 100%;
}
#menu {
height: 70px;
background-color: purple
}
#content {
flex: 1;
height: 100%;
display:flex;
flex-flow: column nowrap;
justify-content: flex-end;
background-color: green;
}
#half_of_content {
flex: 0 0 50%;
background-color: yellow;
}
#footer {
height: 100px;
background-color: cyan
}
<body>
<div id="wrapper">
<div id="menu">
1
</div>
<div id="content">2
<div id="half_of_content">2.1</div>
</div>
<div id="footer" style="">
3
</div>
</div>
</body>
Nesting flexboxes es un poco problemático. Repasé un poco tu marcado añadiendo un contenedor interno con display: flex;
que parece hacer el trabajo. Aquí está el violín (también usando nombres de clase en lugar de identificadores).
<div class="content">
<div class="wrapper-inner">
2
<div class="half">
2.1
</div>
</div>
</div>
.wrapper-inner {
position: absolute;
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
}
Podrías posicionar div id="half_of_content"
.
#content {
flex: 1;
height: 100%;
background-color: green;
position: relative; /* new */
}
#half_of_content {
height: 50%;
background-color: yellow;
position: absolute; /* new */
width: 100%; /* new */
}
Con respecto a su declaración:
Pero parece que Chrome lo trata como la mitad de toda la página en lugar del elemento flexible.
Le diste una height: 100%
al body
height: 100%
. Luego le dio a su hijo ( .wrapper
) una height: 100%
. Luego le dio a su hijo ( .content
) una height: 100%
. Entonces todos tienen la misma altura. Dando al siguiente niño ( #half_of_content
) una height: 50%
sería, naturalmente, 50% de altura del body
.
Sin embargo, con el posicionamiento absoluto, no es necesario que especifique las alturas de los padres .
@Michael_B explicó por qué Chrome se comporta así:
Le diste una
height: 100%
albody
height: 100%
. Luego le dio a su hijo (.wrapper
) unaheight: 100%
. Luego le dio a su hijo (.content
) unaheight: 100%
. Entonces todos tienen la misma altura. Dando al siguiente niño (#half_of_content
) unaheight: 50%
sería, naturalmente, una altura del 50% delbody
.
Sin embargo, Firefox no está de acuerdo porque, de hecho, esa height: 100%
de .content
se ignora y su altura se calcula de acuerdo con flex: 1
.
Es decir, Chrome resuelve el porcentaje con respecto al valor de la propiedad de height
de los padres. Firefox lo hace con respecto a la altura flexible resuelta del padre.
El comportamiento correcto es el de Firefox. De acuerdo con Definite and Indefinite Sizes ,
Si un porcentaje se va a resolver en comparación con el tamaño principal de un artículo flexible , y el artículo flexible tiene una base de flexión definida , y el contenedor flexible tiene un tamaño principal definido , el tamaño principal del artículo flexible se debe tratar como definitivo para el propósito de resolver el porcentaje, y el porcentaje debe resolverse contra el tamaño principal flexionado del elemento flexible (es decir, después de que se haya completado el algoritmo de diseño a continuación para el contenedor flexible del artículo flexible , y el artículo flexible haya adquirido su tamaño).
Aquí hay una solución para Chrome:
#content {
display: flex;
flex-direction: column;
}
#content::after {
content: '''';
flex: 1;
}
#half_of_content {
flex: 1;
height: auto;
}
De esta forma, el espacio disponible en #content
se distribuirá equitativamente entre #half_of_content
y the ::after
pseudo-element.
Suponiendo que #content
no tiene otro contenido, #half_of_content
será del 50%
. En su ejemplo, tiene un 2
allí, por lo que será un poco menos del 50%
.
html,
body {
height: 100%;
margin: 0;
}
#wrapper {
display: flex;
flex-flow: column;
height: 100%;
}
#menu {
height: 70px;
background-color: purple
}
#content {
flex: 1;
height: 100%;
background-color: green;
display: flex;
flex-direction: column;
}
#content::after {
content: '''';
flex: 1;
}
#half_of_content {
flex: 1;
background-color: yellow;
}
#footer {
height: 100px;
background-color: cyan
}
<div id="wrapper">
<div id="menu">
1
</div>
<div id="content">2
<div id="half_of_content">2.1</div>
</div>
<div id="footer" style="">
3
</div>
</div>