Come forzare il div del bambino a raggiungere il 100% dell'altezza del div del genitore senza specificare l'altezza del genitore?


535

Ho un sito con la seguente struttura:

<div id="header"></div>

<div id="main">
  <div id="navigation"></div>
  <div id="content"></div>
</div>

<div id="footer"></div>

La navigazione è a sinistra e il div contenuto è a destra. Le informazioni per il div del contenuto vengono raccolte tramite PHP, quindi ogni volta sono diverse.

Come posso ridimensionare verticalmente la navigazione in modo che la sua altezza sia uguale all'altezza del div del contenuto, indipendentemente dalla pagina caricata?


1
Utilizzare la tabella di visualizzazione sul padre e la cella di tabella sul figlio. Questo renderà figlio fintanto che lo è il genitore. Vedere stackoverflow.com/q/22712489/3429430
user31782

3
Puoi semplicemente impostare display: flex; align-items: stretch;il div # main. E non utilizzare height: 100%per contenuti div #
Igor,

Risposte:


167

NOTA : questa risposta è applicabile ai browser legacy senza supporto per lo standard Flexbox. Per un approccio moderno, consultare: https://stackoverflow.com/a/23300532/1155721


Ti suggerisco di dare un'occhiata alle colonne di uguale altezza con CSS cross-browser e senza hack .

Fondamentalmente, farlo con CSS in un modo compatibile con il browser non è banale (ma banale con le tabelle), quindi trova te stesso una soluzione preconfezionata appropriata.

Inoltre, la risposta varia a seconda che tu voglia il 100% di altezza o uguale altezza. Di solito è uguale altezza. Se è al 100% di altezza, la risposta è leggermente diversa.


7
Questa sembra una buona soluzione fino a quando non si disegna un bordo, border:1px solid bluead esempio container2: il bordo blu si trova sulle prime due colonne, non sulla seconda colonna solo come ci si aspetterebbe.
Julien Kronegg,

@bfritz, una soluzione migliore sarebbe usaredisplay:table
Siler,

537

Per il genitore:

display: flex;

È necessario aggiungere alcuni prefissi, http://css-tricks.com/using-flexbox/ .

Modifica: come notato da @Adam Garner, align-items: stretch; non è necessario. Il suo utilizzo è anche per i genitori, non per i bambini. Se vuoi definire l'allungamento dei bambini, usi align-self.

.parent {
  background: red;
  padding: 10px;
  display:flex;
}

.other-child {
  width: 100px;
  background: yellow;
  height: 150px;
  padding: .5rem;
}

.child {  
  width: 100px;
  background: blue;
}
<div class="parent">
  <div class="other-child">
    Only used for stretching the parent
  </div>
  <div class="child"></div>
</div>


3
IE11 non gioca bene con flexbox e altezze. fai clic su "problemi noti" qui: caniuse.com/#feat=flexbox
adamdport

@SuperUberDuper Beh, puoi usarlo nel bootstrap come questo: jsfiddle.net/prdwaynk Ma se fossi in te, userei la fondazione che è pronta per la produzione con flexbox: foundation.zurb.com/sites/docs/xy-grid.html BS4 avrà anche Flexbox, ma è ancora in versione alpha e penso che le fondamenta siano comunque migliori.
Aiphee,

4
Se stai usando, align-items: centerallora l'articolo di cui hai bisogno per allungare le esigenzealign-self: normal
Dominic,

2
Questa non è una risposta giusta, perché è necessario impostare l'altezza del genitore. La domanda diceva "senza specificare l'altezza dei genitori?".
SkuraZZ

3
@Aiphee downvoting perché sembra che tu non abbia visto la parte sul non dover impostare l'altezza dei genitori proprio lì nel testo della domanda originale, eppure la tua "soluzione" fa esattamente questo.
tylerism

99

Questo è un problema frustrante che viene sempre affrontato dai designer. Il trucco è che devi impostare l'altezza al 100% su BODY e HTML nel tuo CSS.

html,body {
    height:100%;
}

Questo codice apparentemente inutile è definire per il browser cosa significa 100%. Frustrante, sì, ma è il modo più semplice.


9
Tranne che non sempre funziona, ad esempio se si dispone di un elemento posizionato relativo all'interno di uno posizionato in modo assoluto, non forza più hasLayout.
tim

Inoltre, se si vuole sbarazzarsi della barra di scorrimento sul lato destro della finestra (in un Firefox V28), dare la finestra po 'di respiro: html { height: 100%; } body { height: 98%; }.
Chris Middleton,

59
Funziona solo se tutti i genitori hanno un'altezza del 100%, non è sufficiente impostare solo l'html e il corpo, tutti i genitori devono avere un'altezza definita.
RaduM,

97

Trovo che l'impostazione delle due colonne su display: table-cell;invece di float: left;funzioni bene.


10
La stessa SM non lo supporta più, se questo aiuta qualcuno a convincere i propri clienti ...
Heraldmonkey,

4
Questa dovrebbe essere la risposta accettata. I tempi sono cambiati, questa risposta funziona in tutti i browser (con una piccola stranezza in Safari 5.1.17). Due righe di CSS e ottieni immediatamente l'effetto che stai cercando senza alcun inconveniente a cui riesco a pensare.
callmetwan,

7
Solleva questa risposta. Mettiti le spalle ai ragazzi!

Questa è la risposta migliore Sì, possiamo fare una tabella per farlo, ma i suoi dati non sono tabulari, invece trattiamo i div come se fossero celle di tabella ... Fantastico!
Derokorian,

Questo in realtà mi ha messo nella giusta direzione per uno scenario diverso. Nel caso in cui qualcuno stia faticando a lavorare con div quadrati che sono anche contenitori flessibili in Firefox o Edge, ricorda di impostare l'elemento: before da visualizzare: table. Non chiedermi perché, ma lo risolve.
CGodo

56

Se non ti dispiace che il div di navigazione venga troncato in caso di un div contenuto inaspettatamente breve, c'è almeno un modo semplice:

#main {
position: relative;
}

#main #navigation {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 10em; /* or whatever */
}

#main #content {
margin: 0;
margin-left: 10em; /* or whatever width you set for #navigation */
}

Altrimenti c'è la tecnica delle colonne finte .


2
Grazie mille, mi hai salvato la giornata. Non sapevo che si potesse definire sia in alto che in basso e avrebbe funzionato in questo modo.
rubish

Ciò impedirà il ridimensionamento del contenuto del contenitore.
DreamWave,

+1 perché affronta in modo specifico la domanda del PO "Come forzare il div bambino al 100% del div del genitore senza specificare l'altezza del genitore?" Il mio problema non richiedeva colonne (che sono menzionate nel dettaglio della domanda ma non nel titolo principale) ma piuttosto un div dietro l'altro. Questa risposta funziona in entrambe le applicazioni.
Luca

Questa dovrebbe essere la risposta selezionata
Gabriel,

32
#main {
    overflow: hidden;
}
#navigation, #content {
    margin-bottom: -1000px;
    padding-bottom: 1000px;
}

Devo dire che stavo cercando questo tipo di soluzione. Morto semplice e così ovvio che nessuno l'ha capito. Complimenti @Roman!
Greg0ry,

15

usando jQuery:

$(function() {
    function unifyHeights() {
        var maxHeight = 0;
        $('#container').children('#navigation, #content').each(function() {
            var height = $(this).outerHeight();
            // alert(height);
            if ( height > maxHeight ) {
                maxHeight = height;
            }
        });
        $('#navigation, #content').css('height', maxHeight);
    }
    unifyHeights();
});

19
Math.max()sarebbe tuo amico qui.
alex,

1
Non riuscivo a far funzionare il CSS in tutti i casi per me e avevo davvero bisogno di una soluzione rapida. Potrebbe non essere l' approccio più standard , ma questo ha fatto bene il lavoro. Grazie! : -]

1
Quando si utilizza la cssfunzione di JQuery , non è possibile distinguere tra schermo e supporti di stampa, come in genere quando si utilizzano soluzioni CSS pure. Pertanto, potresti avere problemi di stampa.
Julien Kronegg,

12

Prova a rendere il margine inferiore al 100%.

margin-bottom: 100%;

6
o imbottitura inferiore: 100%; non è preciso ma funziona bene in alcune situazioni.
Jason,

padding-bottom fa il trucco nel mio caso. Questa soluzione è molto simile a quella pubblicata da @Roman Kuntyi.
Greg0ry,

10
#main {
   display: table;
} 
#navigation, #content {
   display: table-cell;
}

Guarda questo esempio .


Questo è esattamente quello che stavo facendo, volevo aggiungere una risposta. Stavo anche usando height: 100%ma si scopre che non era necessario.
jcubic,

9

height : <percent>funzionerà solo se hai tutti i nodi padre con altezza percentuale specificata con un'altezza fissa in pixel, ems, ecc. al livello superiore. In questo modo, l'altezza scenderà a cascata verso il tuo elemento.

Puoi specificare il 100% in html ed elementi del corpo come precedentemente indicato da @Travis per avere l'altezza della pagina che scende a cascata verso i tuoi nodi.


9

Dopo lunghe ricerche e tentativi, nulla ha risolto il mio problema tranne

style = "height:100%;"

sui bambini div

e per i genitori applicare questo

.parent {
    display: flex;
    flex-direction: column;
}

inoltre, sto usando bootstrap e questo non ha corrotto il responsive per me.


1
Ho dovuto rimuovere flex-direction: column;per farlo funzionare per me.
Richard Hedges il

6

Sulla base del metodo descritto in questo articolo ho creato. Soluzione meno dinamica:

html:

<div id="container3">
    <div id="container2">
        <div id="container1">
            <div id="col1">Column 1</div>
            <div id="col2">Column 2</div>
            <div id="col3">Column 3</div>
        </div>
    </div>
</div>

Di meno:

/* Changes these variables to adjust your columns */
@col1Width: 60%;
@col2Width: 1%;
@padding: 0%;

/* Misc variable. Do not change */
@col3Width: 100% - @col1Width - @col2Width;

#container3 {
    float: left;
    width: 100%;
    overflow: hidden;
    background-color: red;
    position: relative;

    #container2 {
        float: left;
        width: 100%;
        position: relative;
        background-color: yellow;
        right: @col3Width;

        #container1 {
            float: left;
            width: 100%;
            position: relative;
            right: @col2Width;
            background-color: green;

            #col1 {
                float: left;
                width: @col1Width - @padding * 2;
                position: relative;
                left: 100% - @col1Width + @padding;
                overflow: hidden;
            }

            .col2 {
                float: left;
                width: @col2Width - @padding * 2;
                position: relative;
                left: 100% - @col1Width + @padding + @padding * 2;
                overflow: hidden;
            }

            #col3 {
                float: left;
                width: @col3Width - @padding * 2;
                position: relative;
                left: 100% - @col1Width + @padding + @padding * 4;
                overflow: hidden;
            }
        }
    }
}


3

So che è passato un po 'di tempo da quando è stata fatta la domanda, ma ho trovato una soluzione semplice e ho pensato che qualcuno potesse usarla (mi dispiace per il povero inglese). Eccolo:

CSS

.main, .sidebar {
    float: none;
    padding: 20px;
    vertical-align: top;
}
.container {
    display: table;
}
.main {
    width: 400px;
    background-color: LightSlateGrey;
    display: table-cell;
}
.sidebar {
    width: 200px;
    display: table-cell;
    background-color: Tomato;
}

HTML

<div class="container clearfix">
    <div class="sidebar">
        simple text here
    </div>
    <div class="main">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam congue, tortor in mattis mattis, arcu erat pharetra orci, at vestibulum lorem ante a felis. Integer sit amet est ac elit vulputate lobortis. Vestibulum in ipsum nulla. Aenean erat elit, lacinia sit amet adipiscing quis, aliquet at erat. Vivamus massa sem, cursus vel semper non, dictum vitae mi. Donec sed bibendum ante.
    </div>
</div>

Semplice esempio. Nota che puoi trasformarti in reattività.


Oh, ho dimenticato: se vuoi allineare il contenuto .sidebar nel mezzo, cambia "vertical-align: top" in "vertical-align: middle".
Paula Fleck,

2

La mia soluzione:

$(window).resize(function() {
   $('#div_to_occupy_the_rest').height(
        $(window).height() - $('#div_to_occupy_the_rest').offset().top
    );
});

1

C'è un po 'di contraddizione nel titolo della domanda e nel contenuto. Il titolo parla di un div genitore, ma la domanda fa sembrare che tu voglia che due div fratelli (navigazione e contenuto) abbiano la stessa altezza.

(A) vuoi che sia la navigazione che i contenuti siano al 100% dell'altezza di main, o (b) vuoi che la navigazione e i contenuti siano alla stessa altezza?

Presumo (b) ... se è così, non penso che sarai in grado di farlo data la tua struttura di pagina corrente (almeno, non con CSS puro e senza script). Probabilmente dovresti fare qualcosa del tipo:

<main div>
    <content div>
         <navigation div></div>
    </div>
</div>

e imposta il div del contenuto in modo che abbia un margine sinistro di qualunque sia la larghezza del riquadro di navigazione. In questo modo, il contenuto del contenuto è a destra della navigazione e puoi impostare il div di navigazione al 100% dell'altezza del contenuto.

EDIT: Lo sto facendo completamente nella mia testa, ma probabilmente avresti anche bisogno di impostare il margine sinistro del div di navigazione su un valore negativo o impostare il suo assoluto a sinistra per riportarlo all'estrema sinistra. Il problema è che ci sono molti modi per farlo, ma non tutti saranno compatibili con tutti i browser.


1

[Riferendosi al codice Less di Dmity in un'altra risposta] Immagino che questo sia una specie di "pseudo-codice"?

Da quello che ho capito prova a usare la tecnica delle colonne finte che dovrebbe fare il trucco.

http://www.alistapart.com/articles/fauxcolumns/

Spero che sia di aiuto :)


4
A seconda dell'ordinamento delle risposte, è difficile dire a cosa si riferisca "questo" ... Immagino si tratti del codice di Dmitry. Pertanto, questa osservazione appartiene a un commento sotto la sua risposta! E, per tua informazione, non è uno pseudo-codice, è un codice in meno linguaggio, un modo per definire CSS in modo procedurale.
PhiLho,

1

Questo trucco funziona: aggiungere un elemento finale nella tua sezione di HTML con uno stile di clear: both;

    <div style="clear:both;"></div>

Tutto prima sarà incluso in altezza.


1

dare position: absolute;al bambino ha lavorato nel mio caso


1

Si utilizza CSS Flexbox

.flex-container {
  display: flex;
  background-color: DodgerBlue;
}

.flex-container > div {
  background-color: #f1f1f1;
  margin: 10px;
  padding: 20px;
  font-size: 30px;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>

<div class="flex-container">
  <div>1</div>
  <div>2</div>
  <div>3</div>  
</div>

<p>A Flexible Layout must have a parent element with the <em>display</em> property set to <em>flex</em>.</p>

<p>Direct child elements(s) of the flexible container automatically becomes flexible items.</p>

</body>
</html>


1

Questa risposta non è più ideale poiché la flexbox e la griglia CSS sono state implementate per i CSS. Tuttavia è ancora una soluzione funzionante

Su uno schermo più piccolo probabilmente vorresti mantenere l'altezza automatica poiché col1, col2 e col3 sono impilati l'uno sull'altro.

Tuttavia, dopo un punto di interruzione della query multimediale, i cols dovrebbero apparire uno accanto all'altro con un'altezza uguale per tutte le colonne.

1125 px è solo un esempio di breakpoint di larghezza della finestra dopo il quale si desidera impostare tutte le colonne sulla stessa altezza.

<div class="wraper">
    <div class="col1">Lorem ipsum dolor sit amet.</div>
    <div class="col2">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eos laudantium, possimus sed, debitis amet in, explicabo dolor similique eligendi officia numquam eaque quae illo magnam distinctio odio, esse vero aspernatur.</div>
    <div class="col3">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorem, odio qui praesentium.</div>
</div>

Naturalmente, se necessario, è possibile impostare più punti di interruzione.

<script>
    $(document).ready(function(){
        $(window).on('load resize', function() {
            let vraperH = $('.wraper').height();
            if (window.innerWidth>= 1125) {
              $('.col1').height(vraperH);
              $('.col2').height(vraperH);
              $('.col3').height(vraperH);
            }
            if (window.innerWidth < 1125) {
              $('.col1').height('auto');
              $('.col2').height('auto');
              $('.col3').height('auto');
            }
        });
    });
</script>

1

Ho avuto lo stesso problema, ha funzionato in base alla risposta di Hakam Fostok, ho creato un piccolo esempio, in alcuni casi potrebbe funzionare senza dover aggiungere display: flex;e flex-direction: column;sul contenitore padre

.row {
    margin-top: 20px;
}

.col {
    box-sizing: border-box;
    border: solid 1px #6c757d;
    padding: 10px;
}

.card {
    background-color: #a0a0a0;
    height: 100%;
}

JSFiddle


0

Come mostrato in precedenza, flexbox è il più semplice. per esempio.

#main{ display: flex; align-items:center;}

questo allineerà tutti gli elementi figlio al centro all'interno dell'elemento genitore.


3
questo non risponde alla domanda, vogliono la stessa altezza, non centrare il contenuto
Ryan M


0

Ecco una vecchia demo di moda basata sul position: absolutecontenitore del contenuto e position: relativesul contenitore principale.

Per quanto riguarda il modo moderno di farlo, le scatole flessibili sono le migliori.


-3

Il modo più semplice per farlo è semplicemente fingere. A List Apart lo ha ampiamente trattato nel corso degli anni, come in questo articolo di Dan Cederholm del 2004 .

Ecco come lo faccio di solito:

<div id="container" class="clearfix" style="margin:0 auto;width:950px;background:white url(SOME_REPEATING_PATTERN.png) scroll repeat-y center top;">
    <div id="navigation" style="float:left;width:190px;padding-right:10px;">
        <!-- Navigation -->
    </div>
    <div id="content" style="float:left;width:750px;">
        <!-- Content -->
    </div>
</div>

Puoi facilmente aggiungere un'intestazione a questo disegno avvolgendo #container in un altro div, incorporando il div dell'intestazione come fratello di # container e spostando gli stili di margine e larghezza nel contenitore padre. Inoltre, il CSS dovrebbe essere spostato in un file separato e non tenuto in linea, ecc. Ecc. Infine, la classe clearfix può essere trovata su positioniseverything .

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.