Figlio all'interno del genitore con altezza minima: 100% non eredita l'altezza


167

Ho trovato un modo per fare in modo che un contenitore div occupasse almeno l'intera altezza di una pagina, impostando min-height: 100%;. Tuttavia, quando aggiungo un div nidificato e lo set height: 100%;, non si estende all'altezza del contenitore. C'è un modo per risolverlo?

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
Soluzione moderna: dare il contenitore display:flexed flex-direction:columne dare al bambino flex:1.
Jackocnr,

3
@jackocnr Che non funziona in nessun IE a causa di un bug , è stato corretto in Edge.
Adesivi

Risposte:


146

Si tratta di un bug di webkit (chrome / safari) segnalato, i figli di genitori con altezza minima non possono ereditare la proprietà height: https://bugs.webkit.org/show_bug.cgi?id=26559

Apparentemente anche Firefox è interessato (al momento non è possibile eseguire il test in IE)

Possibile soluzione alternativa:

  • aggiungi posizione: rispetto a #contenimento
  • aggiungi posizione: assoluto in # contenimento-ombra-sinistra

Il bug non mostra quando l'elemento interno ha un posizionamento assoluto.

Vedi http://jsfiddle.net/xrebB/

Modifica il 10 aprile 2014

Dato che al momento sto lavorando a un progetto per il quale ho davvero bisogno di contenitori padre min-heighte di elementi figlio che ereditano l'altezza del contenitore, ho fatto ulteriori ricerche.

Primo: non sono più così sicuro che l'attuale comportamento del browser sia davvero un bug. Le specifiche CSS2.1 dicono:

La percentuale viene calcolata rispetto all'altezza del blocco contenitore della casella generata. Se l'altezza del blocco contenitore non viene specificata in modo esplicito (cioè dipende dall'altezza del contenuto) e questo elemento non è posizionato in modo assoluto, il valore viene calcolato in "auto".

Se metto un'altezza minima sul mio contenitore, non sto specificando esplicitamente la sua altezza, quindi il mio elemento dovrebbe ottenere autoun'altezza. Ed è esattamente quello che fanno Webkit - e tutti gli altri browser.

In secondo luogo, la soluzione alternativa che ho trovato:

Se imposto il mio elemento contenitore su display:tablecon height:inheritesso si comporta esattamente come se gli dessi un valore min-heightdel 100%. E, cosa ancora più importante, se imposto l'elemento figlio sudisplay:table-cell esso erediterà perfettamente l'altezza dell'elemento contenitore, sia esso pari o superiore al 100%.

CSS completo:

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

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

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

Il markup:

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

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


27
Amico, questo non è ancora risolto: S
Mārtiņš Briedis,

Sì, non lo è - vedo che ci sono alcune patch, ma a partire da Chrome 29, non mostra ancora il comportamento previsto. Tuttavia, non funziona neanche in Firefox 23, IE 10, Safari 5 o Opera 12. Almeno tutti i browser sono d'accordo ...
Paul d'Aoust,

3
È una strana lettura delle specifiche per concludere che l'altezza min / max non è esplicita ... e per strano intendo male. Leggendo l'intero paragrafo, nel contesto, questa interpretazione non è corretta. Per chiarire perché "altezza del blocco contenitore", nel contesto, è semanticamente diversa dalla proprietà height. Se invece, il fraseggio fosse " proprietà height del blocco contenitore", allora la tua interpretazione avrebbe senso (ed essere un bug nelle specifiche).
WraithKenny,

1
È il 2019. Abbiamo perso 10 anni di questo bug. La soluzione flessibile ha funzionato per me stackoverflow.com/questions/8468066/…
Ilya Chernov

6
Vengo dall'era del blocco
David Callanan,

174

Aggiungi height: 1pxal contenitore principale. Funziona in Chrome, FF, Safari.


8
In questo modo non si risolve il problema, in effetti si sta scavalcando l'altezza minima: impostazione al 100% che non ottiene nulla che non si possa ottenere con l'altezza: 100% che non è ciò che l'OP vuole
styler

16
L'aggiunta di @styler height: 1px;non sovrascriverà l'altezza minima. Piuttosto il contrario. Questa è la soluzione migliore qui ... demo: jsbin.com/mosaboyo/1/edit
jjenzz

2
Vedi questo per perché height: 1px;funziona stackoverflow.com/questions/2341821/height100-vs-min-height100
Ben Alavi

31
@jjenzz Il problema con questo, che penso che lo styler stesse cercando di ottenere, è che questo non mantiene il tratto di espansione di min-height. Ad esempio, se c'è abbastanza testo, trabocca. Vedi jsbin.com/vuyapitizo/1
binaryfunt

3
Citando il commento di Paul qui sotto: "Ma non consente al contenitore di crescere, il che vanifica lo scopo di usare l'altezza minima". stackoverflow.com/questions/8468066/…
Leo Lei,

103

ho pensato di condividerlo, visto che non l'ho visto da nessuna parte, ed è quello che ho usato per risolvere la mia soluzione.

SOLUZIONE :min-height: inherit;

Avevo un genitore con un'altezza minima specificata e avevo bisogno che un bambino fosse anche quell'altezza.

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

In questo modo il bambino ora agisce come altezza del 100% dell'altezza minima.

Spero che alcune persone lo trovino utile :)


9
Funziona parzialmente, ma il figlio eredita solo il file min-height. Quando l'altezza dei genitori è maggiore, il bambino non si espanderà.
OguzGelal,

1
Mi hai salvato la vita
casamia il

6
Funziona solo quando l'altezza minima è assoluta, non percentuale, AFAICS.
Benjamin,

4
Funziona bene anche se il genitore ha un valore VH! GRAZIE!
user1658080

1
Non adatto ad ogni situazione ma molto utile a volte. Grazie!
Blackbam,

15

Questo è stato aggiunto in un commento di @jackocnr ma l'ho perso. Per i browser moderni penso che questo sia l'approccio migliore.

Rende l'elemento interno riempire l'intero contenitore se è troppo piccolo, ma espande l'altezza del contenitore se è troppo grande.

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

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

1
questo è il migliore poiché flexbox è ampiamente compatibile.
Jose Carlos Ramírez Vásquez,

8

La soluzione di Kushagra Gour funziona (almeno in Chrome e IE) e risolve il problema originale senza dover usare display: table;e display: table-cell;. Vedi plunker: http://plnkr.co/edit/ULEgY1FDCsk8yiRTfOWU

L'impostazione min-height: 100%; height: 1px;sul div esterno fa sì che la sua altezza effettiva sia almeno del 100%, come richiesto. Inoltre, consente al div interno di ereditare correttamente l'altezza.


23
Ma non consente al contenitore di crescere, il che vanifica lo scopo di utilizzare l'altezza minima.
Sal

Avevo bisogno di un involucro per riempire anche l'altezza minima e l'altezza del genitore. Ciò che ha funzionato per me è stato impostare l'altezza minima da ereditare e l'altezza al 100%.
Mr. Duhart,

6

Oltre alle risposte esistenti, ci sono anche unità viewport vhda usare. Snippet semplice di seguito. Naturalmente può essere utilizzato anche insieme calc(), ad esempio min-height: calc(100vh - 200px);quando l'intestazione e il piè di pagina hanno l' 200pxaltezza insieme.

body {
  margin: 0;
}

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


3

Non credo che questo sia un bug con i browser. Tutti si comportano allo stesso modo, ovvero quando si smette di specificare altezze esplicite, l'altezza minima è sostanzialmente un "ultimo passo".

Sembra esattamente come suggeriscono le specifiche CSS 2.1: http://www.w3.org/TR/CSS2/visudet.html#the-height-property

La percentuale viene calcolata rispetto all'altezza del blocco contenitore della casella generata. Se l'altezza del blocco contenitore non viene specificata in modo esplicito (cioè dipende dall'altezza del contenuto) e questo elemento non è posizionato in modo assoluto, il valore viene calcolato in "auto".

Pertanto, poiché il min-heightgenitore non ha un heightset di proprietà esplicito , il valore predefinito è auto.

Esistono alcuni modi per aggirare questo problema utilizzando display: table-cell, o stili più recenti come flexbox, se ciò è possibile per i browser del pubblico di destinazione. Puoi anche sovvertirlo in determinate situazioni usando le proprietà tope bottomsu un elemento interno assolutamente posizionato, che ti dà il 100% di altezza senza specificarlo.


3

Sebbene display: flex;sia stato suggerito qui, considera l'utilizzo display: grid;ora che è ampiamente supportato . Per impostazione predefinita, l'unico figlio di una griglia riempirà interamente il suo genitore.

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

Per i googler:

Questa soluzione alternativa jquery fa sì che #contenimento ottenga automaticamente un'altezza (by, height: auto), quindi ottiene l'altezza effettiva assegnata come valore in 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>

Bella soluzione alternativa, puoi semplicemente impostare l'altezza minima dell'elemento, senza impostare l'altezza su "auto". Ha funzionato per me.
Salvatore Zappalà,

2

Il modo migliore per ottenere questo oggi è usare display: flex;. Tuttavia, potresti riscontrare un problema durante il tentativo di supportare IE11. Secondo https://caniuse.com utilizzando flexbox:

Internet Explorer 11 non allinea correttamente verticalmente gli articoli quando viene utilizzata l'altezza minima

Soluzione compatibile con Internet Explorer

La soluzione è quella di utilizzare display: table;il genitore e display: table-row;il bambino sia height: 100%;come sostituto di min-height: 100%;.

La maggior parte delle soluzioni elencate qui usa display: table , table-rowe / o table-cell, ma non si replicano lo stesso comportamento min-height: 100%;, che è:

  • Eredita l'altezza calcolata del genitore (invece di ereditare la sua heightproprietà);
  • Consentire all'altezza del genitore di superare la sua min-height;

Durante l'utilizzo di questa soluzione, il comportamento è lo stesso e la proprietà min-heightnon è necessaria per aggirare il bug.

Spiegazione

Il motivo per cui funziona è perché, a differenza della maggior parte degli elementi, gli elementi che usano display: tablee table-rowsaranno sempre alti quanto il loro contenuto. Questo fa sì che la loro heightproprietà si comporti in modo simile a min-height.

Soluzione in azione

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

Un'altra soluzione JS, che è semplice e può essere utilizzata per evitare una soluzione non semplice di solo CSS o markup / 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');
}

Direttiva angolare:

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

Per essere usato in questo modo:

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

Grazie per la soluzione direttiva. Questo è quello che ho finito per usare ma non volevo che l'altezza della finestra fosse il minimo; piuttosto volevo ereditare l'altezza minima del genitore, quindi ho cambiato il codice in questo: var height = elm.parent () [0] .offsetHeight;
Sal

1

Questo di solito funziona per me:


.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 per mantenere completo questo argomento, ho trovato una soluzione non esplorata qui usando la posizione fissa.

Nessun overflow

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

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

Questo è ciò che funziona per me con un'altezza basata su percentuale e il genitore continua a crescere in base all'altezza dei bambini. Funziona bene su Firefox, Chrome e Safari.

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

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


-3

dopo aver provato per il nostro! chrome capisce che voglio che l'elemento figlio abbia un'altezza del 100% quando imposto il valore di visualizzazione su blocco in linea. btw setting float lo causerà.

display:inline-block

aggiornare

Questo non funziona. la soluzione è ottenere il parentnode offsetheight e usarlo alla e della pagina con javascript.

<script>
    SomedivElement = document.getElementById('mydiv');
    SomedivElement.style.height = String(nvleft.parentNode.offsetHeight) + 'px';    
</script>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.