Filho dentro dos pais com altura mínima: 100% não herda a altura


166

Encontrei uma maneira de fazer um contêiner div ocupar pelo menos a altura total de uma página, definindo min-height: 100%;. No entanto, quando adiciono uma div aninhada e definida height: 100%;, ela não se estende à altura do contêiner. Existe uma maneira de consertar isso?

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
Solução moderna: dar o recipiente display:flexe flex-direction:columne dar à criança flex:1.
jackocnr

3
@jackocnr Isso não funciona em nenhum IE devido a um bug , foi corrigido no Edge.
Stickers

Respostas:


146

Este é um bug relatado pelo webkit (chrome / safari). Filhos de pais com altura mínima não podem herdar a propriedade height: https://bugs.webkit.org/show_bug.cgi?id=26559

Aparentemente, o Firefox também é afetado (não é possível testar no IE no momento)

Solução possível:

  • adicionar posição: relativo a #containment
  • adicionar posição: absoluto para # contenção-sombra-esquerda

O erro não aparece quando o elemento interno tem posicionamento absoluto.

Veja http://jsfiddle.net/xrebB/

Editar em 10 de abril de 2014

Como atualmente estou trabalhando em um projeto para o qual realmente preciso de contêineres pai min-heighte elementos filho que herdam a altura do contêiner, fiz mais algumas pesquisas.

Primeiro: não tenho mais tanta certeza se o comportamento atual do navegador é realmente um bug. As especificações do CSS2.1 dizem:

A porcentagem é calculada em relação à altura do bloco contendo a caixa gerada. Se a altura do bloco que contém não for especificada explicitamente (isto é, depende da altura do conteúdo) e esse elemento não estiver absolutamente posicionado, o valor será computado para 'automático'.

Se eu colocar uma altura mínima no meu contêiner, não especificarei explicitamente sua altura; portanto, meu elemento deve ter uma autoaltura. E é exatamente isso que o Webkit - e todos os outros navegadores - fazem.

Segundo, a solução alternativa que encontrei:

Se eu definir meu elemento contêiner display:tablecom height:inheritele, ele age exatamente da mesma maneira que se eu desse min-height100%. E - mais importante - se eu definir o elemento filho, display:table-cellele herdará perfeitamente a altura do elemento do contêiner - seja 100% ou mais.

CSS completo:

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

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

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

A marcação:

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

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


25
Cara, isso ainda não está resolvido: S
Mārtiņš Briedis

Sim, não é - vejo que existem alguns patches, mas no Chrome 29, ele ainda não está exibindo o comportamento esperado. No entanto, também não funciona no Firefox 23, IE 10, Safari 5 ou Opera 12. Pelo menos todos os navegadores concordar ...
Paul d'Aoust

3
É uma leitura estranha da especificação para concluir que a altura mínima / máxima não é explícita ... e por estranho eu quero dizer errado. Lendo o parágrafo inteiro, no contexto, essa interpretação está incorreta. Para esclarecer por que "altura do bloco que contém", no contexto, é semanticamente diferente da propriedade height. Se, em vez disso, o fraseado fosse " propriedade height do bloco que o continha", então Sua interpretação faria sentido (e seria um erro na especificação).
WraithKenny

1
É 2019. Perdemos 10 anos de aniversário desse bug. A solução flex funcionou para mim stackoverflow.com/questions/8468066/…
Ilya Chernov

6
Eu sou da era do bloqueio
David Callanan

174

Adicionar height: 1pxao contêiner pai. Funciona no Chrome, FF, Safari.


8
Fazer isso não resolve o problema, efetivamente você está substituindo a configuração min-height: 100% que não alcança nada que não possa ser alcançado com a altura: 100% que não é o que o OP deseja
estilista

16
A adição de @styler height: 1px;não substituirá a altura mínima. Muito pelo contrário. Esta é a melhor solução aqui ... demo: jsbin.com/mosaboyo/1/edit
jjenzz


31
@jjenzz O problema com isso, que eu acho que o estilista estava tentando entender, é que isso não mantém a característica de expansão min-height. Por exemplo, se houver texto suficiente, ele transbordará. Veja jsbin.com/vuyapitizo/1
binaryfunt

3
Citando o comentário de Paulo abaixo: "Mas ele não permite que o recipiente cresça, o que anula o propósito de usar altura mínima". stackoverflow.com/questions/8468066/…
Leo Lei

103

pensei em compartilhar isso, pois não vi isso em lugar nenhum, e é o que costumava consertar minha solução.

SOLUÇÃO :min-height: inherit;

Eu tinha um pai com uma altura mínima especificada e precisava que um filho também tivesse essa 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>

Dessa forma, a criança agora atua como altura 100% da altura mínima.

Espero que algumas pessoas achem isso útil :)


9
Funciona parcialmente, mas o filho herda apenas o min-height. Quando a altura dos pais é maior, o filho não se expande.
OguzGelal

1
Você salvou minha vida
casamia

6
Funciona apenas quando a altura mínima é absoluta, não percentual, AFAICS.
Benjamin

4
Também funciona bem se o pai tiver um valor vh! OBRIGADO!
user1658080

1
Não é adequado para todas as situações, mas é muito útil às vezes. Obrigado!
Blackbam

15

Isso foi adicionado em um comentário por @jackocnr, mas eu perdi. Para navegadores modernos, acho que essa é a melhor abordagem.

Faz com que o elemento interno encha todo o contêiner se ele for muito pequeno, mas expande a altura do contêiner se for muito grande.

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

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

1
isso é o melhor, pois o flexbox é amplamente compatível.
Jose Carlos Ramírez Vásquez

8

A solução de Kushagra Gour funciona (pelo menos no Chrome e no IE) e resolve o problema original sem a necessidade de usar display: table;e display: table-cell;. Veja plunker: http://plnkr.co/edit/ULEgY1FDCsk8yiRTfOWU

A configuração min-height: 100%; height: 1px;na div externa faz com que sua altura real seja de pelo menos 100%, conforme necessário. Também permite que a div interna herde corretamente a altura.


23
Mas não permite que o contêiner cresça, o que anula o propósito de usar altura mínima.
Sal

Eu precisava de um invólucro para preencher também a altura e altura mín. O que funcionou para mim foi definir min-height para herdar e height para 100%.
Sr. Duhart

6

Além das respostas existentes, também há unidades de janela de exibição vhpara usar. Snippet simples abaixo. É claro que também pode ser usado junto calc(), por exemplo, min-height: calc(100vh - 200px);quando o cabeçalho e o rodapé da página têm 200pxaltura juntos.

body {
  margin: 0;
}

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


3

Eu não acredito que isso seja um bug nos navegadores. Todos se comportam da mesma maneira - ou seja, quando você para de especificar alturas explícitas, min-height é basicamente um "último passo".

Parece ser exatamente como a especificação do CSS 2.1 sugere: http://www.w3.org/TR/CSS2/visudet.html#the-height-property

A porcentagem é calculada em relação à altura do bloco contendo a caixa gerada. Se a altura do bloco que contém não for especificada explicitamente (isto é, depende da altura do conteúdo) e esse elemento não estiver absolutamente posicionado, o valor será computado para 'automático'.

Portanto, como o min-heightpai não possui um heightconjunto de propriedades explícito , o padrão é automático.

Existem algumas maneiras de contornar isso, possivelmente usando display: table-cellestilos mais recentes, como o flexbox, se isso for possível para os navegadores do seu público-alvo. Você também pode subverter isso em determinadas situações usando as propriedades tope bottomem um elemento interno absolutamente posicionado, o que fornece 100% de altura sem especificar isso.


3

Embora display: flex;tenha sido sugerido aqui, considere usar display: grid;agora que é amplamente suportado . Por padrão, o único filho de uma grade preencherá inteiramente seu pai.

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 os googlers:

Essa solução alternativa para jquery faz com que #containment obtenha uma altura automaticamente (por, height: auto) e, em seguida, obtenha a altura real atribuída como um valor de pixel.

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

Solução legal, você pode simplesmente definir a altura mínima do elemento, sem definir a altura para 'automático'. Funcionou para mim.
Salvatore Zappalà

2

A melhor maneira de conseguir isso hoje em dia é usar display: flex;. No entanto, você pode ter um problema ao tentar oferecer suporte ao IE11. De acordo com https://caniuse.com usando flexbox:

O IE 11 não alinha verticalmente os itens corretamente quando a altura mínima é usada

Solução compatível com Internet Explorer

A solução é usar display: table;no pai e display: table-row;no filho, ambos height: 100%;como substitutos min-height: 100%;.

A maioria das soluções listadas aqui usam display: table, table-rowe / ou table-cell, mas eles não replicar o mesmo comportamento min-height: 100%;, que é:

  • Herdar a altura calculada do pai (em vez de herdar sua heightpropriedade);
  • Permita que a altura dos pais exceda a sua min-height;

Ao usar esta solução, o comportamento é o mesmo e a propriedade min-heightnão é necessária, o que permite contornar o bug.

Explicação

A razão pela qual funciona é porque, diferentemente da maioria dos elementos, os elementos que usam display: tablee table-rowsempre serão tão altos quanto seu conteúdo. Isso faz com que suas heightpropriedades se comportem de maneira semelhante a min-height.

Solução em ação

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

Outra solução JS, que é fácil e pode ser usada para evitar uma solução não-fácil apenas de CSS ou de marcação / hacky extra.

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');
}

Diretiva 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 usado assim:

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

Obrigado pela solução diretiva. Foi o que acabei usando, mas não queria que a altura da janela fosse a mínima; eu queria herdar a altura mínima do pai, então mudei o código para este: var height = elm.parent () [0] .offsetHeight;
Sal

1

Isso geralmente funciona para mim:


.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

Apenas para manter esse assunto completo, encontrei uma solução não explorada aqui usando a posição fixa.

Sem estouro

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>

Com estouro

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

Isso é o que funciona para mim com a altura baseada em porcentagem e os pais ainda crescendo de acordo com a altura dos filhos. Funciona bem no Firefox, Chrome e Safari.

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

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


-3

depois de tentar para o nosso! chrome entende que eu quero que o elemento filho tenha 100% de altura quando defino o valor de exibição como bloco embutido. btw configuração flutuante irá causar isso.

display:inline-block

atualizar

isto não está a funcionar. a solução é obter o offsetheight do nó pai e usá-lo na e da página com javascript.

<script>
    SomedivElement = document.getElementById('mydiv');
    SomedivElement.style.height = String(nvleft.parentNode.offsetHeight) + 'px';    
</script>
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.