CSS: espande l'altezza DIV del figlio mobile all'altezza del genitore


451

Ho la struttura della pagina come:

<div class="parent">
    <div class="child-left floatLeft">
    </div>

    <div class="child-right floatLeft">
    </div>
</div>

Ora, il child-leftDIV avrà più contenuti, quindi l' parentaltezza del DIV aumenta secondo il DIV figlio.

Ma il problema è che l' child-rightaltezza non sta aumentando. Come posso rendere la sua altezza uguale a quella del genitore?


Risposte:


459

Per l' parentelemento, aggiungi le seguenti proprietà:

.parent {
    overflow: hidden;
    position: relative;
    width: 100%;
}

quindi per .child-rightquesti:

.child-right {
    background:green;
    height: 100%;
    width: 50%;
    position: absolute;
    right: 0;
    top: 0;
}

Trova risultati più dettagliati con esempi CSS qui e maggiori informazioni su colonne di uguale altezza qui .


14
Il tuo CSS si traduce in un comportamento indefinito: l'altezza del genitore dipende dall'altezza dei bambini, ma i bambini hanno un'altezza percentuale definita in termini del genitore: questo non è valido e probabilmente non funzionerà in modo cross-browser.
Eamon Nerbonne,

1
Vedo che non stai fluttuando tutto, quindi è definito a costo di non ridimensionare se mai la colonna di destra cresce più a lungo di quella di sinistra (cosa che in effetti non è il caso nella domanda del PO).
Eamon Nerbonne,

4
Sì, è necessario aggiungere questo: padding-bottom: 32768px; margine inferiore: -32768px; ai bambini.
Michael,

3
Funziona fintanto che la colonna di destra avrà meno contenuti rispetto alla sinistra, altrimenti verrà ritagliata. Inoltre ho modificato la risposta per omettere le dichiarazioni inutili.
Christoph,

3
@MatthewBlackford: è un "hack" in quanto impedisce il collasso dei margini. Potresti impedire il collasso dei margini in altri modi, ad esempio utilizzando un bordo trasparente 1px, ma in sostanza, ma la cosa importante qui è evitare il collasso dei margini. Non userei questa soluzione se non come ultima risorsa poiché causa strani errori di layout e ritagli inattesi (o contenuti sovrapposti) quando i tuoi presupposti risultano difettosi. In breve: non vuoi farlo a meno che non sia davvero necessario.
Eamon Nerbonne,

206

Una soluzione comune a questo problema utilizza il posizionamento assoluto o i float ritagliati, ma questi sono difficili in quanto richiedono una messa a punto estesa se le colonne cambiano in numero + dimensioni e che è necessario assicurarsi che la colonna "principale" sia sempre la più lunga. Invece, suggerirei di utilizzare una delle tre soluzioni più robuste:

  1. display: flex: di gran lunga la soluzione più semplice e migliore e molto flessibile - ma non supportata da IE9 e precedenti.
  2. tableoppure display: table: molto semplice, molto compatibile (praticamente tutti i browser di sempre), abbastanza flessibile.
  3. display: inline-block; width:50% con un margine negativo: abbastanza semplice, ma i bordi in fondo alla colonna sono un po 'complicati.

1. display:flex

Questo è davvero semplice ed è facile adattarsi a layout più complessi o più dettagliati, ma flexbox è supportato solo da IE10 o versioni successive (oltre ad altri browser moderni).

Esempio: http://output.jsbin.com/hetunujuma/1

HTML pertinente:

<div class="parent"><div>column 1</div><div>column 2</div></div>

Css rilevanti:

.parent { display: -ms-flex; display: -webkit-flex; display: flex; }
.parent>div { flex:1; }

Flexbox supporta molte più opzioni, ma per avere semplicemente un numero qualsiasi di colonne è sufficiente quanto sopra!

2. <table>odisplay: table

Un modo semplice ed estremamente compatibile per farlo è usare un table- ti consiglio di provarlo prima se hai bisogno del supporto vecchio IE . Hai a che fare con le colonne; divs + float semplicemente non sono il modo migliore per farlo (per non parlare del fatto che più livelli di div nidificati solo per aggirare le limitazioni CSS non è quasi più "semantico" rispetto al semplice utilizzo di una semplice tabella). Se non si desidera utilizzare l' tableelemento, considerare cssdisplay: table (non supportato da IE7 e precedenti).

Esempio: http://jsfiddle.net/emn13/7FFp3/

HTML pertinente: (ma considera invece l'uso di un semplice<table>)

<div class="parent"><div>column 1</div><div>column 2</div></div>

Css rilevanti:

.parent { display: table; }
.parent > div {display: table-cell; width:50%; }
/*omit width:50% for auto-scaled column widths*/

Questo approccio è molto più robusto rispetto all'utilizzo overflow:hiddencon i float. Puoi aggiungere praticamente qualsiasi numero di colonne; puoi farli ridimensionare automaticamente se vuoi; e mantieni la compatibilità con i browser antichi. A differenza della soluzione float richiesta, non è nemmeno necessario sapere in anticipo quale colonna è la più lunga; l'altezza si adatta bene.

BACIO: non usare hack float a meno che non sia necessario. Se IE7 è un problema, sceglierei comunque una semplice tabella con colonne semantiche su una soluzione trucco-CSS difficile da mantenere e meno flessibile ogni giorno.

A proposito, se hai bisogno che il tuo layout sia reattivo (es. Nessuna colonna su piccoli telefoni cellulari) puoi usare una @mediaquery per tornare al layout a blocchi semplici per schermi di piccole dimensioni - funziona sia che tu usi <table>o con qualsiasi altro display: tableelemento.

3. display:inline blockcon un margine negativo hack.

Un'altra alternativa è usare display:inline block.

Esempio: http://jsbin.com/ovuqes/2/edit

HTML pertinente: (l'assenza di spazi tra idivtag è significativa!)

<div class="parent"><div><div>column 1</div></div><div><div>column 2</div></div></div>

Css rilevanti:

.parent { 
    position: relative; width: 100%; white-space: nowrap; overflow: hidden; 
}

.parent>div { 
    display:inline-block; width:50%; white-space:normal; vertical-align:top; 
}

.parent>div>div {
    padding-bottom: 32768px; margin-bottom: -32768px; 
}

Questo è leggermente complicato e il margine negativo significa che il "vero" fondo delle colonne è oscurato. Questo a sua volta significa che non puoi posizionare nulla rispetto alla parte inferiore di quelle colonne perché è tagliato da overflow: hidden. Nota che oltre ai blocchi inline, puoi ottenere un effetto simile con i float.


TL; DR : utilizzare flexbox se è possibile ignorare IE9 e precedenti; altrimenti prova una tabella (css). Se nessuna di queste opzioni funziona per te, ci sono hack di margine negativo, ma questi possono causare strani problemi di visualizzazione che sono facili da perdere durante lo sviluppo e ci sono limitazioni di layout di cui devi essere consapevole.


1
Buono, ma vale la pena notare che non è possibile utilizzare i margini tra queste celle (e l'imbottitura non sarà di aiuto se si desidera che siano in stile).
Wordpressor

3
border-spacing:10px;sull'elemento table verrà introdotta una spaziatura marginale. In alternativa, è possibile aggiungere colonne extra (vuote) dove si desidera spazio aggiuntivo. E potresti anche aggiungere imbottitura all'interno delle celle della tabella; quell'imbottitura verrà comunque inclusa in background, quindi potrebbe non essere quello che vuoi. Ma hai ragione sul fatto che non è flessibile come un margine normale. E non puoi posizionare nulla in relazione alle colonne, il che potrebbe essere un problema.
Eamon Nerbonne,

1
Quindi è meglio un layout senza tavolo o no?
dinamico

3
Devo dire: sono d'accordo che in questo caso una semplice tabella è più che sufficiente. Il problema è che esiste una visione comune per ignorare ogni layout con tabella
dinamica il

3
Il problema con la tabella è che quando lo schermo viene ridimensionato a una larghezza inferiore (design reattivo), le celle della tabella vengono schiacciate invece di affiancarne una sopra la successiva. Il secondo metodo con imbottitura inferiore: 32768px; margine inferiore: -32768px; è abbastanza sorprendente e fa quasi esattamente quello di cui avevo bisogno ... grazie per quello ... il bordo inferiore è un problema però ...
Serj Sagan,

23

Per il genitore:

display: flex;

Per bambini:

align-items: stretch;

Dovresti aggiungere alcuni prefissi, controlla caniuse.


2
Non lo consiglierei. IE9 è ancora una cosa.

La ringrazio per la risposta; Funziona bene! "Dovresti aggiungere alcuni prefissi, controlla caniuse." cosa intendi con quella linea? Puoi aggiungere qualche informazione in più per i principianti?
Md Sifatul Islam,

@MdSifatulIslam Vai qui: caniuse.com/#feat=flexbox Puoi vedere se alcuni browser di cui hai bisogno per supportare hanno bisogno del prefisso delle funzioni.
Aiphee,

18

Ho trovato molte risposte, ma probabilmente la soluzione migliore per me è

.parent { 
  overflow: hidden; 
}
.parent .floatLeft {
  # your other styles
  float: left;
  margin-bottom: -99999px;
  padding-bottom: 99999px;
}

Puoi controllare altre soluzioni qui http://css-tricks.com/fluid-width-equal-height-columns/


Non ho idea del perché questo lavoro, ma risolve il mio problema come un incantesimo. Grazie
Combina il

Funziona anche per me. Anche se non è il modo pulito. Grazie!
Mark Anthony Uy,

18
hacky come l'inferno. Non lo consiglio per applicazioni di produzione
Federico

questo è incredibile haha. Non pensavo che avrebbe funzionato davvero
Tom McDonough,

11

Si prega di impostare div genitore su overflow: hidden
poi in div figlio è possibile impostare una grande quantità per il riempimento in basso. per esempio
padding-bottom: 5000px
allora margin-bottom: -5000px
e poi tutte le div del bambino saranno l'altezza del genitore.
Ovviamente questo non funzionerà se stai cercando di inserire contenuti nel div parent (al di fuori di altri div che sono)

.parent{
    border: 1px solid black;
    overflow: hidden;
    height: auto;
}
.child{
    float: left;
    padding-bottom: 1500px;
    margin-bottom: -1500px;
}
.child1{
    background: red;
    padding-right: 10px;    
}
.child2{
    background: green;
    padding-left: 10px;
}
<div class="parent">
    <div class="child1 child">
        One line text in child1
    </div>
    <div class="child2 child">
        Three line text in child2<br />
        Three line text in child2<br />
        Three line text in child2
    </div>
</div>

Esempio: http://jsfiddle.net/Tareqdhk/DAFEC/


sembra un po 'sporco, ma ha funzionato per me - l'unica soluzione su questa domanda. Ho provato questo usando Twitter Bootstrap.
Cukabeka,

8

Il genitore ha un'altezza? Se imposti l'altezza dei genitori in questo modo.

div.parent { height: 300px };

Quindi puoi far allungare il bambino a tutta altezza in questo modo.

div.child-right { height: 100% };

MODIFICARE

Ecco come lo faresti usando JavaScript.


il genitore non ha un'altezza fissa. Si sta espandendo secondo l'altezza del bambino sinistro.
Veera,

Ah, ho pensato tanto, quindi avrai bisogno di JavaScript, lo aggiungerò tra un secondo.
Olical,

@Il link JSFiddle originale è interrotto. Rimuovilo o aggiorna la risposta. Grazie!
itsmysterybox

1
Il link a js ora dà un 404
Chanoch,

5

La visualizzazione della tabella CSS è ideale per questo:

.parent {
  display: table;
  width: 100%;
}
.parent > div {
  display: table-cell;
}
.child-left {
  background: powderblue;
}
.child-right {
  background: papayawhip;
}
<div class="parent">
  <div class="child-left">Short</div>
  <div class="child-right">Tall<br>Tall</div>
</div>

Risposta originale (presupponendo che qualsiasi colonna possa essere più alta):

Stai cercando di rendere l'altezza dei genitori dipendente dall'altezza dei bambini e l'altezza dei bambini dall'altezza dei genitori. Non calcola. Le colonne Faux CSS sono la soluzione migliore. C'è più di un modo per farlo. Preferirei non usare JavaScript.


Buon punto. Che ne dici se l'altezza dei bambini dipende dall'altezza del fratello più alto (sia che sia determinato dall'altezza del genitore o meno), e non dal genitore? Immagino che non si possa fare in CSS.
mikato

No, i fratelli non possono influenzare l'altezza l'uno dell'altro. Tuttavia, display: table+ display: table-celllayout produrrà il risultato desiderato.
Salman A

Ottimo aggiornamento! Tuttavia, ho finito per provare questo e volevo avere una separazione degli spazi bianchi tra le div / celle e ho finito per dover fare div interni all'interno dei div della tabella-cella per ottenere ciò e poi ovviamente ho perso la capacità di farli usare tutta l'altezza perché i div interni non erano div a celle di tabella - esattamente lo stesso problema. Qualche idea per quello? Tipo di spaziatura cellulare mancante ora.
mikato,

Ah, c'è una spaziatura dei bordi nei CSS! stackoverflow.com/questions/339923/… Sono stato in grado di far funzionare bene i div simili a una tabella con la separazione degli spazi usando la spaziatura dei bordi. Ora ho la possibilità di fare in modo che le celle della tabella (blocchi di sfondo colorati) utilizzino l'intera altezza del genitore o meno mediante un uso intelligente dei div delle celle della tabella.
Mikato,

Solo un gotcha in cui mi sono imbattuto: non puoi usarlo con float: stackoverflow.com/questions/20110217/…
Joshua Pinter

4

Di recente l'ho fatto sul mio sito Web usando jQuery. Il codice calcola l'altezza del div più alto e imposta gli altri div alla stessa altezza. Ecco la tecnica:

http://www.broken-links.com/2009/01/20/very-quick-equal-height-columns-in-jquery/

Non credo height:100%funzionerà, quindi se non conosci esplicitamente le altezze div non penso che ci sia una soluzione CSS pura.


1
Dovresti attivare questo almeno su pronto, ridimensionamento, cambio di orientamento, ridimensionamento del carattere.
netAzione

4

L'ho usato per una sezione di commento:

.parent {
    display: flex;
    float: left;
    border-top:2px solid black;
    width:635px;
    margin:10px 0px 0px 0px;
    padding:0px 20px 0px 20px;
    background-color: rgba(255,255,255,0.5);
}
    
.child-left {
	align-items: stretch;
	float: left;
	width:135px;
	padding:10px 10px 10px 0px;
	height:inherit;
	border-right:2px solid black;
}

.child-right {
	align-items: stretch;
	float: left;
	width:468px;
	padding:10px;
}
<div class="parent">
  <div class="child-left">Short</div>
  <div class="child-right">Tall<br>Tall</div>
</div>

Potresti spostare il bambino da destra a destra, ma in questo caso ho calcolato con precisione le larghezze di ogni div.


1
la prima cosa che mi è venuta in mente è stata l'altezza: ereditare non è sicuro del motivo per cui nessuno ha votato
Andreas

3

Se sei a conoscenza di bootstrap puoi farlo facilmente usando la proprietà 'flex'. Tutto ciò che devi fare è passare sotto le proprietà css al div genitore

.homepageSection {
  overflow: hidden;
  height: auto;
  display: flex;
  flex-flow: row;
}

dov'è il .homepageSectionmio genitore div. Ora aggiungi div bambino nel tuo html come

<div class="abc col-md-6">
<div class="abc col-md-6">

dove abc è il div del mio bambino. Puoi controllare la parità di altezza in entrambi i div del bambino indipendentemente dal bordo semplicemente dando il confine al div del bambino


0
<div class="parent" style="height:500px;">
<div class="child-left floatLeft" style="height:100%">
</div>

<div class="child-right floatLeft" style="height:100%">
</div>
</div>

Ho usato lo stile in linea solo per dare un'idea.


-2

Ho imparato questo trucco in un'intervista di internato. La domanda originale è come garantire che l'altezza di ciascun componente superiore in tre colonne abbia la stessa altezza che mostra tutto il contenuto disponibile. Fondamentalmente creare un componente figlio che è invisibile che rende l'altezza massima possibile.

<div class="parent">
    <div class="assert-height invisible">
        <!-- content -->
    </div>
    <div class="shown">
        <!-- content -->
    </div>
</div>
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.