¿Cómo puedo hacer que los niños Flexbox tengan el 100% de la altura de sus padres?

459

Estoy tratando de llenar el espacio vertical de un elemento flexible dentro de un 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>

Y aquí está el JSFiddle

flex-2-child no llena la altura requerida, excepto en los dos casos donde:

  1. flex-2 tiene una altura del 100% (lo cual es extraño porque un elemento flexible tiene un 100% por defecto + tiene errores en Chrome)
  2. flex-2-child tiene una posición absoluta que también es inconveniente

Esto no funciona en Chrome o Firefox actualmente.

Raz
fuente
¿Cuál es el problema con el uso de la altura: 100%; para .flex-2?
rmagnum2002
Desafía el propósito del elemento flexible que es llenar el contenido por sí mismo y me está dando el error más extraño en cromo, donde la altura vuelve a cero cada vez que cambio el tamaño de la ventana
Raz
3
En realidad, la última versión de Firefox es la única que funciona correctamente
Raz
1
Actualmente, existen diferencias significativas en el comportamiento entre los navegadores cuando se trata de representar alturas porcentuales en flexbox: stackoverflow.com/a/35537510/3597276
Michael Benjamin
2
Sí, Chrome tiene algunos problemas, especialmente con flexboxes anidados. Por ejemplo, tengo un cuadro flexible anidado con hijos que tienen, height:100%pero en su lugar están renderizando con altura natural. Y lo extraño es que si cambio su altura a auto, entonces se renderizan como height:100%estaba tratando de hacer. Definitivamente no es intuitivo si así es como debería funcionar.
trusktr

Respuestas:

238

Utilizar align-items: stretch

Similar a la respuesta de David Storey, mi solución es:

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

Alternativamente a align-items , puede usar align-selfsolo el .flex-2-childelemento que desea estirar.

BT
fuente
77
stretch: esta debería ser la respuesta elegida.
Dave Everitt
1
Definitivamente esta es la mejor respuesta para la pregunta. Funciona perfectamente.
marcias
Sí, esta es la mejor respuesta para esta pregunta.
Øyvind Bråthen
20
no olvide eliminar también height: 100%del componente secundario que desea tener la misma altura que el principal
Ilham Wahabi GX
Agregue eliminación height: 100%a la respuesta: casi me doy por vencido y solo vi esto en el último momento antes de volver a hacerlo absolute, lo que viene con todo tipo de problemas.
Peter
274

He respondido una pregunta similar aquí .

Sé que ya has dicho que position: absolute;es inconveniente, pero funciona. Consulte a continuación para obtener más información sobre cómo solucionar el problema de cambio de tamaño.

También vea este jsFiddle para una demostración, aunque solo he agregado prefijos webkit tan abiertos en Chrome.

Básicamente tiene 2 problemas que trataré por separado.

  1. Hacer que el niño de un elemento flexible llene la altura al 100%
    • Establecer position: relative;en el padre del niño.
    • Establecer position: absolute;en el niño.
    • Luego puede establecer el ancho / alto según sea necesario (100% en mi muestra).
  2. Arreglando el "capricho" de desplazamiento de cambio de tamaño en Chrome
    • Póngase overflow-y: auto;el div desplazable.
    • El div desplazable debe tener una altura explícita especificada. Mi muestra ya tiene una altura del 100%, pero si ya no se aplica, puede especificarheight: 0;

Consulte esta respuesta para obtener más información sobre el problema del desplazamiento.

Brett Postin
fuente
10
El punto 1) funciona perfectamente en Chrome, Firefox no necesita la posición absoluta.
yuri
224

Si entiendo correctamente, ¿quieres que flex-2-child llene la altura y el ancho de su padre, de modo que el área roja esté completamente cubierta por el verde?

Si es así, solo necesita configurar flex-2 para usar flexbox:

.flex-2 {
    display: flex;  
}

Luego dígale a flex-2-child que se vuelva flexible:

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

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

La razón es que flex-2-child no es un elemento de flexbox, pero su padre sí lo es.

David Storey
fuente
¿Cómo puedo hacer lo mismo, solo con una altura del 100% y cada niño es 50/50?
Ricky Levi
77
Tenga en cuenta que si usa "align-items: center" no podrá usar esta corrección ya que sus artículos ahora tendrán la misma altura.
Neil Monroe
10
@NeilMonroe Todavía puede usar align-items: centersi usa align-self: stretchsolo un niño.
BT
1
Hola @David, probé tu solución, funciona bien para la dirección flexible: diseño de fila, parece que no funciona con la dirección flexible: diseño de columna, o tengo algún lugar incorrecto en el código. ¿Podría ayudar a verificar por qué en este violín jsfiddle.net/78o54Lmv , la caja interna no ocupará la altura total de su padre?
huan feng
Tengo que agregar min-height: 100vh;al .flex-2elemento para que funcione. ¡Gracias por la ayuda!
Tenaciousd93
24

Supongo que el comportamiento de Chrome es más consistente con la especificación CSS (aunque es menos intuitivo). De acuerdo con las especificaciones de Flexbox, el stretchvalor predeterminado de la align-selfpropiedad cambia solo el valor utilizado de la "propiedad de tamaño cruzado" del elemento ( heighten este caso). Y, según tengo entendido la especificación CSS2.1 , las alturas porcentuales se calculan a partir del valor especificado de los padres height, no de su valor utilizado. El valor especificado de los padres heightno se ve afectado por ninguna propiedad flex y sigue siendoauto .

Configuración explícitas height: 100%hace que sea formalmente posible calcular la altura porcentual del niño, al igual que el establecimiento height: 100%de htmlhace posible calcular la altura porcentaje de bodyen CSS2.1.

Ilya Streltsyn
fuente
2
¡Exactamente! Para poner esto en práctica, solo agregue height:100%a .flex-2. Aquí está el jsfiddle .
CourtDemone
77
El comportamiento de Chrome es más coherente con la interpretación del equipo de Chrome de la especificación CSS. Si bien podría interpretarse de esa manera, hay formas mucho mejores de interpretarlo, cualquiera de las cuales no nos hubiera atrapado en este bazar, comportamiento molesto e irritante. Deberían haberlo pensado más.
WraithKenny
1
@ RickDoesburg, esto fue hace más de un año, pero creo que tuve que recurrir a elementos de altura fija. Desearía que estos navegadores actuaran juntos. Realmente estoy empezando a disgustar el espacio móvil.
Jordan
1
Establecer un elemento secundario de un contenedor de flexbox vertical me height: 100%está dando resultados muy extraños en Chrome. Parece que esto hace que la "altura especificada" se establezca en la altura total del contenedor , en lugar de la altura del elemento en sí, por lo que se produce un desplazamiento no deseado cuando otros elementos tienen tamaños calculados en relación con él.
Julio
13

Encontré la solución por mí mismo, supongamos que tiene el CSS a continuación:

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

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

En este caso, establecer la altura al 100% no funcionará, así que lo que hago es establecer la margin-bottomregla en auto, como:

.child {
  margin-bottom: auto;
}

y el niño estará alineado con el superior del padre, también puede usar la align-selfregla de todos modos si lo prefiere.

.child {
  align-self: flex-start;
}
usuario3896501
fuente
Un buen truco, pero el problema es: si el niño es una barra lateral y tiene un color de fondo, el espacio del margen sigue siendo blanco.
Boris Burkov
¡Lo bueno de esta solución es que la altura del padre puede ser dinámica! Las soluciones anteriores requieren que el padre tenga una altura establecida. Gracias por esto.
Bribbons
4

Una idea sería que display:flex;con flex-direction: row;está llenando el containerdiv con .flex-1y .flex-2, pero eso no significa que .flex-2tenga un valor predeterminado, height:100%;incluso si se extiende a toda su altura y para tener un elemento hijo ( .flex-2-child) con el height:100%;que deberá establecer el padre height:100%;o usar display:flex;con flex-direction: row;en el .flex-2div también.

Por lo que sé display:flex, no se extenderá la altura de todos los elementos secundarios al 100%.

Una pequeña demostración, eliminó la altura .flex-2-childy se usó display:flex;en .flex-2: http://jsfiddle.net/2ZDuE/3/

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

Esto también se puede resolver con align-self: stretch;el elemento que queremos estirar.

A veces es deseable estirar solo un elemento en una configuración de 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
fuente
-7

.envase { . . . . elementos de alineación: estiramiento; . . . . }

HRK
fuente
55
Bienvenido a stackoverflow. Necesita explicar completamente su respuesta, y lo que contribuye es diferente de las respuestas existentes. Ver stackoverflow.com/help/how-to-answer
Simon.SA
1
Su respuesta parece ser la misma que la de BT (escrita más de tres años antes) pero expresada mucho peor.
Quentin
-12

Esta es mi solución usando css +

En primer lugar, si el primer hijo (flex-1) debería ser 100 px, no debería ser flex. En css +, de hecho, puede configurar elementos flexibles y / o estáticos (columnas o filas) y su ejemplo se vuelve tan fácil como esto:

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

contenedor css:

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

y obviamente incluye css + 0.2 core

escuchar el violín

Marco Allori
fuente