Fai in modo che div (altezza) occupi l'altezza rimanente del genitore


107

http://jsfiddle.net/S8g4E/

Ho un container divcon due bambini. Il primo bambino ha una determinata altezza. Come posso fare in modo che il secondo bambino occupi lo "spazio libero" del contenitore divsenza dare un'altezza specifica?

Nell'esempio, il rosa divdovrebbe occupare anche lo spazio bianco.


Simile a questa domanda: come fare in modo che div occupi l'altezza rimanente?

Ma non voglio dare una posizione assoluta .


Ho provato anche a dare l'altezza del secondo figlio del 100% ma non funziona: jsfiddle.net/S8g4E/1
Alvaro

Risposte:


156

L'espansione del #downbambino per riempire lo spazio rimanente #containerpuò essere eseguita in vari modi a seconda del supporto del browser che si desidera ottenere e se o meno#up ha un'altezza definita .

Campioni

Griglia

Il gridlayout del CSS offre ancora un'altra opzione, anche se potrebbe non essere così semplice come il modello Flexbox. Tuttavia, richiede solo lo stile dell'elemento contenitore:

.container { display: grid; grid-template-rows: 100px }

Il grid-template-rows definisce la prima riga come 100px altezza fissa, e rimangono righe tenderanno automaticamente per riempire lo spazio rimanente.

Sono abbastanza sicuro che IE11 richieda -ms-prefissi, quindi assicurati di convalidare la funzionalità nei browser che desideri supportare.

Flexbox

Il modulo di layout a scatola flessibileflexbox di CSS3 ( ) è ora ben supportato e può essere molto facile da implementare. Poiché è flessibile, funziona anche quando #upnon ha un'altezza definita.

#container { display: flex; flex-direction: column; }
#down { flex-grow: 1; }

È importante notare che il supporto di IE10 e IE11 per alcune proprietà flexbox può essere difettoso e IE9 o versioni precedenti non hanno alcun supporto.

Altezza calcolata

Un'altra facile soluzione è utilizzare l' unità funzionale CSS3calc , come sottolinea Alvaro nella sua risposta , ma richiede che l'altezza del primo figlio sia un valore noto:

#up { height: 100px; }
#down { height: calc( 100% - 100px ); }

È ampiamente supportato, con le uniche eccezioni degne di nota: <= IE8 o Safari 5 (nessun supporto) e IE9 (supporto parziale). Alcuni altri problemi includono l'uso di calc in combinazione con transform o box-shadow , quindi assicurati di testare in più browser se questo ti preoccupa.

Altre alternative

Se è necessario un supporto precedente, è possibile aggiungere height:100%;a #downrenderà il div rosa a tutta altezza, con un avvertimento. Provocherà un trabocco per il contenitore, perché lo #upsta spingendo verso il basso.

Pertanto, potresti aggiungere overflow: hidden;al contenitore per risolverlo.

In alternativa, se l'altezza di #upè fissa, puoi posizionarlo assolutamente all'interno del contenitore e aggiungere un padding-top a #down.

E un'altra opzione sarebbe quella di utilizzare un display da tavolo:

#container { width: 300px; height: 300px; border: 1px solid red; display: table;}
#up { background: green; display: table-row; height: 0; }
#down { background: pink; display: table-row;}​

4
Vorrei che #down avesse #container height - #up height. Quindi overflow nascosto non è quello che sto cercando. E inoltre non voglio usare la posizione assoluta. Grazie!
Alvaro

@Alvaro, ho aggiunto un'altra opzione, utilizzando i display da tavolo. Lo svantaggio qui è la compatibilità. PS Un elemento posizionato assolutamente all'interno di un contenitore con position: relative;posizionarlo rispetto al contenitore, non alla finestra. Quindi, questa dovrebbe essere un'opzione praticabile.
utente

2
La riga di tabella dovrebbe funzionare per te, vedi questo jsFiddle per la prova. Il metodo posizione assoluta non sarà in grado di produrre gli stessi risultati di questo violino, quindi possiamo cancellarlo dalla lista (#down e #container avranno la stessa altezza in quello scenario).
utente

3
Stai chiedendo molto, @Alvaro. CSS non è un linguaggio di scripting; non può calcolare cose. Sei bloccato con illusioni o js.
Jezen Thomas,

1
@ Quantastical, grazie per il tuo aiuto, ma nella tua ultima modifica hai appena copiato la risposta che ho postato. Qualche menzione a riguardo almeno sarebbe carino.
Alvaro

24

Sono passati quasi due anni da quando ho posto questa domanda. Ho appena inventato css calc () che risolve questo problema e ho pensato che sarebbe stato bello aggiungerlo nel caso qualcuno avesse lo stesso problema. (A proposito, ho finito per usare la posizione assoluta).

http://jsfiddle.net/S8g4E/955/

Ecco il css

#up { height:80px;}
#down {
    height: calc(100% - 80px);//The upper div needs to have a fixed height, 80px in this case.
}

E maggiori informazioni al riguardo qui: http://css-tricks.com/a-couple-of-use-cases-for-calc/

Supporto browser: http://caniuse.com/#feat=calc


1
Anch'io ho utilizzato i CSS3 in calccui l'ampio supporto del browser non è così importante (IE8 e versioni precedenti e Safari 5 non lo supportano).
utente

3
Qualche modo per fare lo stesso con #upun'altezza dinamica ?
Adam Waite

@AdamWaite, con un'altezza #up dinamica, ti consigliamo di utilizzare la soluzione di overflow descritta nell'altra risposta.
utente

5

La mia risposta usa solo CSS e non usa overflow: hidden o display: table-row. Richiede che il primo bambino abbia davvero una determinata altezza, ma nella tua domanda affermi che solo il secondo bambino deve avere la sua altezza non specificata, quindi credo che dovresti trovarlo accettabile.

html

<div id="container">
    <div id="up">Text<br />Text<br />Text<br /></div>
    <div id="down">Text<br />Text<br />Text<br /></div>
</div>

css

#container { width: 300px; height: 300px; border:1px solid red;}
#up { background: green; height: 63px; float:left; width: 100% }
#down { background:pink; padding-top: 63px; height: 100%; box-sizing: border-box; }

http://jsfiddle.net/S8g4E/288/


2

controlla la demo - http://jsfiddle.net/S8g4E/6/

usa css -

#container { width: 300px; height: 300px; border:1px solid red; display: table;}
#up { background: green; display: table-row; }
#down { background:pink; display: table-row;}

Dovresti aggiungere height: 1pxa #upper assicurarti che prenda la quantità minima di altezza. Ecco il supporto del browser per display: table: caniuse.com/css-table
trentaduesimo

Potresti mostrarmi come è possibile ottenere questa soluzione in questo esempio "più complesso", per favore: jsfiddle.net/fyNX4 Grazie mille
Alvaro

2

A meno che io non abbia frainteso, puoi semplicemente aggiungere height: 100%;e overflow:hidden;a #down.

#down { 
    background:pink; 
    height:100%; 
    overflow:hidden;
}​

Dimostrazione dal vivo

Modifica: poiché non si desidera utilizzare overflow:hidden;, è possibile utilizzare display: table;per questo scenario; tuttavia, non è supportato prima di IE 8. ( display: table;supporto )

#container { 
    width: 300px; 
    height: 300px; 
    border:1px solid red;
    display:table;
}

#up { 
    background: green;
    display:table-row;
    height:0; 
}

#down { 
    background:pink;
    display:table-row;
}​

Dimostrazione dal vivo

Nota: hai detto che vuoi che l' #downaltezza sia l' #containeraltezza meno l' #upaltezza. La display:table;soluzione fa esattamente questo e questo jsfiddle lo rappresenterà abbastanza chiaramente.


1
Non voglio che #down superi l'altezza del #container
Alvaro

L'ho appena notato. Puoi aggiungere overflow:hiddena per nascondere il contenuto extra.
Josh Mein,

1
Copio / incolla quello che ho detto a MrSlayer: vorrei che #down avesse #container height - #up height. Quindi overflow nascosto non è quello che sto cercando. E inoltre non voglio usare la posizione assoluta. Grazie!
Alvaro

Il problema con questo è che se ripristini i due div nel tuo esempio, il div verde è all'esterno.
Ced

Questo non risponde affatto alla domanda. Indica "Per occupare tutta l'altezza rimanente", anche se questa occupa tutta l'altezza rimanente, ci sarà un overflow.
Giridhar Karnik

1

Puoi usare i float per spingere il contenuto verso il basso:

http://jsfiddle.net/S8g4E/5/

Hai un contenitore di dimensioni fisse:

#container {
    width: 300px; height: 300px;
}

Il contenuto può scorrere accanto a un galleggiante. A meno che non impostiamo il float su tutta la larghezza:

#up {
    float: left;
    width: 100%;
}

Mentre #upe #downcondividi la prima posizione, #downil contenuto di può iniziare solo dopo la fine del floated #up:

#down {
    height:100%;
}​

Nota che in #uprealtà copre la parte superiore di #down: jsfiddle.net/thirtydot/S8g4E/9
trentadot il

Sì, è così che funziona. Ma se OP non ha bisogno di un bordo arrotondato o di qualcos'altro #up, allora è probabilmente accettabile.
biziclop

Questa soluzione è vicina, ma vorrei che #down avesse #container height - #up height. (Nella tua soluzione #down height = #container height). Grazie '
Alvaro

1
@Alvaro: Perché deve essere così? Questa soluzione sembra corretta nella maggior parte dei casi, anche se è solo un'illusione.
trenta punti,

Bene, questa domanda è un esempio semplificato da questo esempio più "complesso": jsfiddle.net/fyNX4 Non funzionerebbe, no?
Alvaro

1

Astratto

Non ho trovato una risposta completamente soddisfacente, quindi ho dovuto scoprirla da solo.

Le mie esigenze:

  • l'elemento dovrebbe occupare esattamente lo spazio rimanente o quando la dimensione del suo contenuto è minore o maggiore della dimensione dello spazio rimanente (nel secondo caso dovrebbe essere mostrata la barra di scorrimento );
  • la soluzione dovrebbe funzionare quando l' altezza genitore è calcolata e non specificata ;
  • calc()non dovrebbe essere usato poiché l'elemento rimanente non dovrebbe sapere nulla delle dimensioni di un altro elemento;
  • dovrebbe essere utilizzata una tecnica di layout moderna e familiare come i flexbox .

La soluzione

  • Trasforma in flexbox tutti i genitori diretti con altezza calcolata (se presente) e il genitore successivo la cui altezza è specificata ;
  • Specifica flex-grow: 1a tutti i genitori diretti con altezza calcolata (se presente) e l'elemento in modo che si occupano tutto lo spazio rimanente quando la dimensione contenuto dell'elemento è minore;
  • Specificare flex-shrink: 0a tutti gli elementi di flessione con altezza fissa in modo da non diventare più piccolo quando la dimensione dei contenuti elemento è più grande della dimensione spazio rimanente;
  • Specificare overflow: hiddena tutti i genitori diretti con altezza calcolata (se presente) per disabilitare lo scorrimento e impedire la visualizzazione di contenuto in eccesso;
  • Specificare overflow: autoper l'elemento per consentire lo scorrimento al suo interno.

JSFiddle (l'elemento ha genitori diretti con altezza calcolata)

JSFiddle (caso semplice: nessun genitore diretto con altezza calcolata)


-3

Non sono sicuro che possa essere fatto esclusivamente con i CSS, a meno che non ti senta a tuo agio nel fingere con illusioni. Forse usa la risposta di Josh Mein e imposta #containersu overflow:hidden.

Per quello che vale, ecco una soluzione jQuery:

var contH = $('#container').height(),
upH = $('#up').height();
$('#down').css('height' , contH - upH);

Grazie stavo cercando una soluzione Css pura.
Alvaro
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.