Niño dentro del padre con altura mínima: 100% no hereda altura


166

Encontré una manera de hacer un contenedor div para ocupar al menos la altura completa de una página, mediante la configuración min-height: 100%;. Sin embargo, cuando agrego un div y un conjunto anidados height: 100%;, no se estira hasta la altura del contenedor. ¿Hay alguna forma de arreglarlo?

html, body {
  height: 100%;
  margin: 0;
}

#containment {
  min-height: 100%;
  background: pink;
}

#containment-shadow-left {
  height: 100%;
  background: aqua;
}
<div id="containment">
  <div id="containment-shadow-left">
    Hello World!
  </div>
</div>


27
Solución de hoy en día: dar el contenedor display:flexy flex-direction:columny dar al niño flex:1.
jackocnr

3
@jackocnr Eso no funciona en ningún IE debido a un error , se solucionó en Edge.
Pegatinas

Respuestas:


146

Este es un error del kit web (chrome / safari), los hijos de padres con altura mínima no pueden heredar la propiedad de altura: https://bugs.webkit.org/show_bug.cgi?id=26559

Aparentemente, Firefox también se ve afectado (no se puede probar en IE en este momento)

Posible solución:

  • agregar posición: relativa a #contención
  • agregar posición: absoluto a # contenedor-sombra-izquierda

El error no se muestra cuando el elemento interno tiene un posicionamiento absoluto.

Ver http://jsfiddle.net/xrebB/

Editar el 10 de abril de 2014

Como actualmente estoy trabajando en un proyecto para el que realmente necesito contenedores principales min-heighty elementos secundarios que hereden la altura del contenedor, investigué un poco más.

Primero: ya no estoy tan seguro de si el comportamiento actual del navegador es realmente un error. Las especificaciones CSS2.1 dicen:

El porcentaje se calcula con respecto a la altura del bloque que contiene la caja generada. Si la altura del bloque contenedor no se especifica explícitamente (es decir, depende de la altura del contenido), y este elemento no está en una posición absoluta, el valor se calcula como 'auto'.

Si pongo una altura mínima en mi contenedor, no estoy especificando explícitamente su altura, por lo que mi elemento debería tener una autoaltura. Y eso es exactamente lo que hace Webkit, y todos los demás navegadores.

En segundo lugar, la solución que encontré:

Si configuro mi elemento contenedor display:tablecon height:inheritél, actúa exactamente de la misma manera que si le diera un min-height100%. Y, lo que es más importante, si configuro el elemento hijo display:table-cellheredará perfectamente la altura del elemento contenedor, ya sea 100% o más.

CSS completo:

html, body {
  height: 100%;
  margin: 0;
}

#container {
  background: green;
  display: table;
  height: inherit;
  width: 100%;
}

#content {
  background: red;
  display: table-cell;
}

El marcado:

<div id="container">
  <div id="content">
      <p>content</p>
  </div>
</div>

Ver http://jsfiddle.net/xrebB/54/ .


25
Hombre, esto todavía no está solucionado: S
Mārtiņš Briedis

Sí, no lo es. Veo que hay algunos parches, pero a partir de Chrome 29, todavía no muestra el comportamiento esperado. Sin embargo, tampoco funciona en Firefox 23, IE 10, Safari 5 u Opera 12. Al menos todos los navegadores están de acuerdo ...
Paul d'Aoust

3
Es una lectura extraña de la especificación para concluir que la altura mínima / máxima no es explícita ... y por extraño quiero decir equivocado. Leyendo todo el párrafo, en contexto, esta interpretación es incorrecta. Para aclarar por qué, la "altura del bloque contenedor", en contexto, es semánticamente diferente de la propiedad de altura. Si en cambio, la frase era "altura propiedad de del bloque contenedor", entonces su interpretación tendría sentido (y sería un error en la especificación).
WraithKenny

1
Es 2019. Nos hemos perdido el décimo aniversario de este error. La solución flex me funcionó stackoverflow.com/questions/8468066/…
Ilya Chernov

66
Soy de la era del encierro
David Callanan

174

Añadir height: 1pxal contenedor principal. Funciona en Chrome, FF, Safari.


8
Hacer esto no resuelve el problema, efectivamente está anulando la altura mínima: 100% de configuración que no logra nada que no se pueda lograr con la altura: 100%, que no es lo que el OP quiere
styler

16
La adición de @styler height: 1px;no anulará la altura mínima. Todo lo contrario. Esta es la mejor solución aquí ... demo: jsbin.com/mosaboyo/1/edit
jjenzz

2

31
@jjenzz El problema con esto, que creo que Styler estaba tratando de resolver, es que esto no conserva el rasgo de expansión de min-height. Por ejemplo, si hay suficiente texto, se desbordará. Ver jsbin.com/vuyapitizo/1
binaryfunt

3
Citando el comentario de Paul a continuación: "Pero no permite que el contenedor crezca, lo que frustra el propósito de usar altura mínima". stackoverflow.com/questions/8468066/…
Leo Lei

103

pensé en compartir esto, ya que no lo vi en ningún lado, y es lo que solía solucionar mi solución.

SOLUCION :min-height: inherit;

Tenía un padre con una altura mínima especificada, y necesitaba que un niño también tuviera esa altura.

.parent {
  min-height: 300px;
  background-color: rgba(255,255,0,0.5); //yellow
}

.child {
  min-height: inherit;
  background-color: rgba(0,255,0,0.5); //blue
}

p {
  padding: 20px;
  color: red;
  font-family: sans-serif;
  font-weight: bold;
  text-align: center;
}
<div class="parent">
  <div class="child">
    <p>Yellow + Blue = Green :)</p>
  </div>
</div>

De esta manera, el niño ahora actúa como altura al 100% de la altura mínima.

Espero que algunas personas encuentren esto útil :)


9
Funciona parcialmente, pero el hijo solo hereda el min-height. Cuando la altura de los padres es mayor, el niño no se expandirá.
OguzGelal

1
Me salvaste la vida
casamia

66
Solo funciona cuando la altura mínima es absoluta, no porcentaje, AFAICS.
Benjamin

44
¡También funciona bien si el padre tiene un valor vh! ¡GRACIAS!
user1658080

1
No es adecuado para todas las situaciones, pero a veces es muy útil. ¡Gracias!
Blackbam

15

Esto fue agregado en un comentario por @jackocnr pero lo extrañé. Para los navegadores modernos, creo que este es el mejor enfoque.

Hace que el elemento interno llene todo el contenedor si es demasiado pequeño, pero expande la altura del contenedor si es demasiado grande.

#containment {
  min-height: 100%;
  display: flex;
  flex-direction: column;
}

#containment-shadow-left {
  flex: 1;
}

1
Este es el mejor ya que Flexbox es ampliamente compatible.
José Carlos Ramírez Vásquez

8

La solución de Kushagra Gour funciona (al menos en Chrome e IE) y resuelve el problema original sin tener que usar display: table;y display: table-cell;. Ver plunker: http://plnkr.co/edit/ULEgY1FDCsk8yiRTfOWU

La configuración min-height: 100%; height: 1px;en el div externo hace que su altura real sea al menos del 100%, según sea necesario. También permite que el div interno herede correctamente la altura.


23
Pero no permite que el contenedor crezca, lo que frustra el propósito de usar altura mínima.
Sal

También necesitaba un contenedor para llenar la altura y altura mín. De los padres. Lo que funcionó para mí fue establecer la altura mínima para heredar y la altura al 100%.
Sr. Duhart el

6

Además de las respuestas existentes, también hay unidades de ventana gráfica vhpara usar. Fragmento simple a continuación. Por supuesto, también se puede usar junto con calc(), por ejemplo, min-height: calc(100vh - 200px);cuando el encabezado y el pie de página tienen 200pxaltura juntos.

body {
  margin: 0;
}

.child {
  min-height: 100vh;
  background: pink;
}
<div class="parent">
  <div class="child"></div>
</div>


3

No creo que esto sea un error con los navegadores. Todos se comportan de la misma manera, es decir, una vez que deja de especificar alturas explícitas, la altura mínima es básicamente un "último paso".

Parece ser exactamente como sugiere la especificación CSS 2.1: http://www.w3.org/TR/CSS2/visudet.html#the-height-property

El porcentaje se calcula con respecto a la altura del bloque que contiene la caja generada. Si la altura del bloque contenedor no se especifica explícitamente (es decir, depende de la altura del contenido), y este elemento no está en una posición absoluta, el valor se calcula como 'auto'.

Por lo tanto, como el min-heightpadre no tiene un explícitoheight conjunto de propiedades , el valor predeterminado es auto.

Hay algunas formas de evitar esto, posiblemente, mediante el uso de display: table-cellestilos más nuevos, como flexbox, si eso es posible para los navegadores de su público objetivo. También puede subvertir esto en ciertas situaciones mediante el uso de las propiedades topy bottomen un elemento interno absolutamente posicionado, lo que le da una altura del 100% sin especificarlo.


3

Aunque display: flex;se ha sugerido aquí, considere usar display: grid;ahora que es ampliamente compatible . Por defecto, el único hijo de una cuadrícula llenará por completo su padre.

html, body {
  height: 100%;
  margin: 0;
  padding: 0; /* Don't forget Safari */
}

#containment {
  display: grid;
  min-height: 100%;
  background: pink;
}

#containment-shadow-left {
  background: aqua;
}


2

Para googlers:

Esta solución alternativa de jquery hace que #containment obtenga una altura automáticamente (por, height: auto), luego obtiene la altura real asignada como un valor de píxel.

<script type="text/javascript">
<!--
    $(function () {

        // workaround for webkit-bug http://stackoverflow.com/a/8468131/348841

        var rz = function () {
            $('#containment')
            .css('height', 'auto')
            .css('height', $('#containment').height() + 'px');
        };

        $(window).resize(function () {
            rz();
        });

        rz();

    })
-->
</script>

Buena solución, solo puede establecer la altura mínima del elemento, sin establecer la altura en 'auto'. Funcionó para mi.
Salvatore Zappalà

2

La mejor manera de lograr esto hoy en día es usarlo display: flex;. Sin embargo, es posible que tenga un problema cuando intente admitir IE11. De acuerdo con https://caniuse.com usando flexbox:

IE 11 no alinea verticalmente los elementos correctamente cuando se usa min-height

Solución compatible con Internet Explorer

La solución es usar tanto display: table;en el padre como display: table-row;en el niño height: 100%;como sustituto de min-height: 100%;.

La mayoría de las soluciones enumeradas aquí usan display: table, table-rowy / o table-cell, pero no replican el mismo comportamiento que min-height: 100%;, que es:

  • Heredar la altura calculada del padre (en lugar de heredar su height propiedad);
  • Permita que la altura del padre exceda la suya min-height;

Al usar esta solución, el comportamiento es el mismo y la propiedad min-height no es necesaria, lo que permite evitar el error.

Explicación

La razón por la que funciona es porque, a diferencia de la mayoría de los elementos, los elementos que usan display: tabley table-rowsiempre serán tan altos como su contenido. Esto hace que su heightpropiedad se comporte de manera similar amin-height .

Solución en acción

html, body {
  height: 100px;
  margin: 0;
}

#containment {
  display: table;
  height: 100%;
  background: pink;
  width: 100%;
}

#containment-shadow-left {
  display: table-row;
  height: 100%;
  background: aqua;
}

#content {
  padding: 15px;
}

#demo {
  display: none;
  background-color: red;
  height: 200px;
}

#demo-checkbox:checked ~ #demo {
  display: block;
}
<div id="containment">
  <div id="containment-shadow-left">
    <div id="content">
      <input id="demo-checkbox" type="checkbox">
      <label for="demo-checkbox">Click here for overflow demo</label>
      <div id="demo">This is taller than #containment</div>
    </div>
  </div>
</div>


1

Otra solución de JS, que es fácil y puede usarse para evitar una solución de marcado / hacky extra fácil de CSS o no fácil.

function minHeight(elm, percent) {
  var windowHeight = isNaN(window.innerHeight) ? 
                     window.clientHeight : window.innerHeight;
  var height = windowHeight * percent / 100;
  elm.style.minHeight = height + 'px';
}

W / jQuery:

function minHeight($elm, percent) {
  var windowHeight = $(window).height();
  var height = windowHeight * percent / 100;
  $elm.css('min-height', height + 'px');
}

Directiva angular:

myModule.directive('minHeight', ['$window', function($window) {
  return {
    restrict: 'A',
    link: function(scope, elm, attrs) {
      var windowHeight = isNaN($window.innerHeight) ? 
               $window.clientHeight : $window.innerHeight;
      var height = windowHeight * attrs.minHeight / 100;
      elm.css('min-height', height + 'px');
    }
  };
}]);

Para ser utilizado así:

<div>
  <!-- height auto here -->
  <div min-height="100">
    <!-- This guy is at least 100% of window height but grows if needed -->
  </div>
</div>

Gracias por la solución directiva. Eso es lo que terminé usando pero no quería que la altura de la ventana fuera la mínima; más bien quería heredar la altura mínima del padre, así que cambié el código a esto: var height = elm.parent () [0] .offsetHeight;
Sal

1

Usualmente esto funciona para mi:


.parent {
  min-height: 100px;
  background-color: green;
  display: flex;
}
.child {
  height: inherit;
  width: 100%;
  background-color: red;
}
<!DOCTYPE html>
<html>
  <body>
    <div class="parent">
      <div class="child">
      </div>
    </div>
  </body>
</html>

0

Solo para mantener este tema completo, encontré una solución no explorada aquí usando la posición fija.

Sin desbordamiento

html, body, .wrapper, .parent, .child {
  position: fixed;
  top: 0; 
  bottom: 0;
  left: 0;
  right: 0;
  margin: 0;
  padding: 0;
  height: 100%;
}

.child {
  overflow: auto;
  background: gray;
}

.height-50 {
  height: 50%;
  width: 5em;
  margin: 10px auto;
  background: cyan;
}
<div class="wrapper">
  <div class="parent">
    <div class="child">
      
      <div class="height-50"></div>
      
    </div>
  </div>
</div>

Con desbordamiento

html, body, .wrapper, .parent, .child {
  position: fixed;
  top: 0; 
  bottom: 0;
  left: 0;
  right: 0;
  margin: 0;
  padding: 0;
  height: 100%;
}

.child {
  overflow: auto;
  background: gray;
}

.height-150 {
  height: 150%;
  width: 5em;
  margin: 10px auto;
  background: cyan;
}
<div class="wrapper">
  <div class="parent">
    <div class="child">
      
      <div class="height-150"></div>
      
    </div>
  </div>
</div>


-2

Esto es lo que funciona para mí con una altura basada en porcentajes y los padres siguen creciendo de acuerdo con la altura de los niños. Funciona bien en Firefox, Chrome y Safari.

.parent {
  position: relative;
  min-height: 100%;
}

.child {
  min-height: 100vh;
}
<div class="parent">
    <div class="child"></div>
  </div>


-3

después de intentar por el nuestro! Chrome entiende que quiero que el elemento hijo tenga una altura del 100% cuando configuro el valor de visualización en bloque en línea. por cierto, el flotador lo causará.

display:inline-block

actualizar

esto no está funcionando. la solución es obtener la altura de desplazamiento del nodo principal y usarla en la página y con JavaScript.

<script>
    SomedivElement = document.getElementById('mydiv');
    SomedivElement.style.height = String(nvleft.parentNode.offsetHeight) + 'px';    
</script>
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.