CSS - Erweitern Sie die Float-Child-DIV-Höhe auf die Parent-Höhe


450

Ich habe die Seitenstruktur wie folgt:

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

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

Jetzt hat der child-leftDIV mehr Inhalt, sodass die parentGröße des DIV gemäß dem untergeordneten DIV zunimmt.

Das Problem ist jedoch, dass die child-rightHöhe nicht zunimmt. Wie kann ich seine Höhe an die des Elternteils anpassen?


Antworten:


459

Fügen Sie für das parentElement die folgenden Eigenschaften hinzu:

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

dann für .child-rightdiese:

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

Detailliertere Ergebnisse mit CSS-Beispielen finden Sie hier und weitere Informationen zu Spalten gleicher Höhe finden Sie hier .


14
Ihr CSS führt zu undefiniertem Verhalten - die Größe der Eltern hängt von der Größe der Kinder ab, aber die Kinder haben eine prozentuale Größe, die in Bezug auf die Eltern definiert ist: Dies ist ungültig und funktioniert wahrscheinlich nicht browserübergreifend.
Eamon Nerbonne

1
Ich sehe, dass Sie nicht alles schweben lassen - das wird also auf Kosten der Nicht-Skalierung definiert, wenn die rechte Spalte jemals länger als die linke wächst (was in der Frage des OP tatsächlich nicht der Fall ist).
Eamon Nerbonne

4
Ja, Sie müssen Folgendes hinzufügen: padding-bottom: 32768px; Rand unten: -32768px; zu den Kindern.
Michael

3
Dies funktioniert, solange die rechte Spalte garantiert weniger Inhalt enthält als die linke, sonst wird sie abgeschnitten. Außerdem habe ich die Antwort bearbeitet, um die nutzlosen Erklärungen wegzulassen.
Christoph

3
@MatthewBlackford: Es ist ein "Hack", der verhindert, dass der Rand zusammenbricht. Sie können das Zusammenfallen von Rändern auf andere Weise verhindern, z. B. durch Verwendung eines transparenten 1-Pixel-Rahmens. Im Wesentlichen ist es jedoch wichtig, dass Sie das Zusammenfallen von Rändern vermeiden. Ich würde diese Lösung nur als letzten Ausweg verwenden, da sie seltsame Layoutfehler und unerwartetes Zuschneiden (oder überlagerten Inhalt) verursacht, wenn sich Ihre Annahmen als fehlerhaft herausstellen. Kurz gesagt: Sie möchten dies nur tun, wenn Sie es wirklich müssen.
Eamon Nerbonne

205

Eine übliche Lösung für dieses Problem verwendet die absolute Positionierung oder zugeschnittene Floats. Diese sind jedoch insofern schwierig, als sie eine umfassende Optimierung erfordern, wenn sich Ihre Spalten in Anzahl + Größe ändern, und dass Sie sicherstellen müssen, dass Ihre "Hauptsäule" immer die längste ist. Stattdessen würde ich vorschlagen, dass Sie eine von drei robusteren Lösungen verwenden:

  1. display: flex: bei weitem die einfachste und beste Lösung und sehr flexibel - aber von IE9 und älter nicht unterstützt.
  2. tableoder display: table: sehr einfach, sehr kompatibel (so ziemlich jeder Browser), ziemlich flexibel.
  3. display: inline-block; width:50% mit einem negativen Rand-Hack: recht einfach, aber die Ränder am unteren Ende der Spalte sind etwas knifflig.

1. display:flex

Dies ist sehr einfach und lässt sich leicht an komplexere oder detailliertere Layouts anpassen. Flexbox wird jedoch nur von IE10 oder höher (zusätzlich zu anderen modernen Browsern) unterstützt.

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

Relevantes HTML:

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

Relevante CSS:

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

Flexbox unterstützt viel mehr Optionen, aber um einfach eine beliebige Anzahl von Spalten zu haben, reicht das oben Genannte aus!

2. <table>oderdisplay: table

Eine einfache und äußerst kompatible Möglichkeit, dies zu tun, ist die Verwendung von a table- ich würde empfehlen, dass Sie dies zuerst versuchen, wenn Sie Unterstützung für alte IE benötigen . Sie haben es mit Spalten zu tun; divs + floats sind einfach nicht der beste Weg, dies zu tun (ganz zu schweigen von der Tatsache, dass mehrere Ebenen verschachtelter divs, nur um CSS-Einschränkungen zu umgehen, kaum "semantischer" sind als nur die Verwendung einer einfachen Tabelle). Wenn Sie das tableElement nicht verwenden möchten , ziehen Sie CSS in Betrachtdisplay: table (von IE7 und älter nicht unterstützt).

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

Relevantes HTML: (aber erwägen Sie<table>stattdessen dieVerwendung einer Ebene)

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

Relevante CSS:

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

Dieser Ansatz ist weitaus robuster als die Verwendung overflow:hiddenmit Floats. Sie können so ziemlich eine beliebige Anzahl von Spalten hinzufügen. Sie können sie automatisch skalieren lassen, wenn Sie möchten. und Sie behalten die Kompatibilität mit alten Browsern. Im Gegensatz zur Float-Lösung müssen Sie auch nicht vorher wissen, welche Spalte am längsten ist. Die Höhe skaliert ganz gut.

KISS: Verwenden Sie keine Float-Hacks, es sei denn, Sie müssen dies ausdrücklich tun. Wenn IE7 ein Problem darstellt, würde ich jeden Tag eine einfache Tabelle mit semantischen Spalten über einer schwer zu wartenden, weniger flexiblen Trick-CSS-Lösung auswählen.

Übrigens, wenn Sie möchten, dass Ihr Layout reagiert (z. B. keine Spalten auf kleinen Mobiltelefonen), können Sie mithilfe einer @mediaAbfrage auf das einfache Blocklayout für kleine Bildschirmbreiten zurückgreifen - dies funktioniert unabhängig davon, ob Sie es verwenden <table>oder nichtdisplay: table Element verwenden.

3. display:inline blockmit einem negativen Margin Hack.

Eine andere Alternative ist zu verwenden display:inline block.

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

Relevantes HTML: (Das Fehlen von Leerzeichen zwischen dendivTags ist signifikant!)

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

Relevante CSS:

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

Dies ist etwas schwierig und der negative Rand bedeutet, dass der "wahre" Boden der Spalten verdeckt ist. Dies bedeutet wiederum, dass Sie nichts relativ zum unteren Rand dieser Spalten positionieren können, da dies durch abgeschnitten wird overflow: hidden. Beachten Sie, dass Sie zusätzlich zu Inline-Blöcken mit Floats einen ähnlichen Effekt erzielen können.


TL; DR : Verwenden Sie Flexbox, wenn Sie IE9 und älter ignorieren können. Andernfalls versuchen Sie es mit einer (CSS-) Tabelle. Wenn keine dieser Optionen für Sie funktioniert, gibt es Hacks mit negativen Margen, die jedoch zu seltsamen Anzeigeproblemen führen können, die während der Entwicklung leicht übersehen werden können, und es gibt Layoutbeschränkungen, die Sie beachten müssen.


1
Gut, aber es ist erwähnenswert, dass Sie keine Ränder zwischen diesen Zellen verwenden können (und das Auffüllen hilft nicht, wenn Sie möchten, dass sie gestaltet werden).
Wordpressor

3
border-spacing:10px;Auf dem Tabellenelement wird ein randartiger Abstand eingeführt. Alternativ können Sie zusätzliche (leere) Spalten hinzufügen, in denen Sie zusätzlichen Speicherplatz benötigen. Sie können auch Auffüllungen in die Tabellenzellen einfügen. Diese Polsterung wird jedoch im Hintergrund angezeigt, sodass dies möglicherweise nicht das ist, was Sie möchten. Aber Sie haben Recht, dass es nicht ganz so flexibel ist wie ein normaler Spielraum. Und Sie können nichts relativ zu den Spalten positionieren, was ein Problem sein kann.
Eamon Nerbonne

1
Also ist es besser ein tabellenloses Layout oder nicht?
dynamische

3
Ich muss sagen: Ich stimme Ihnen zu, dass in diesem Fall eine einfache Tabelle mehr als genug ist. Das Problem ist, dass es eine gemeinsame Ansicht gibt, jedes Layout mit Tabelle zu ignorieren
dynamisch

3
Das Problem mit der Tabelle besteht darin, dass bei einer Größenänderung des Bildschirms auf eine kleinere Breite (responsives Design) die Tabellenzellen gequetscht werden, anstatt eine über die nächste zu kacheln. Die zweite Methode mit Polsterung unten: 32768px; Rand unten: -32768px; ist ziemlich erstaunlich und macht fast genau das, was ich brauchte ... danke dafür ... Border Bottom ist allerdings ein Problem ...
Serj Sagan

23

Für die Eltern:

display: flex;

Für Kinder:

align-items: stretch;

Sie sollten einige Präfixe hinzufügen, überprüfen Sie caniuse.


2
Würde es nicht empfehlen. IE9 ist immer noch eine Sache.

Vielen Dank für Ihre Antwort; Es funktioniert gut! "Sie sollten einige Präfixe hinzufügen, caniuse überprüfen." Was meinst du mit dieser Zeile? Können Sie Anfängern etwas mehr Informationen hinzufügen?
Md Sifatul Islam

@MdSifatulIslam Gehen Sie hier: caniuse.com/#feat=flexbox Sie können sehen, ob ein Browser, den Sie unterstützen müssen, das Funktionspräfix benötigt.
Aiphee

18

Ich habe viele Antworten gefunden, aber wahrscheinlich ist die beste Lösung für mich

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

Sie können andere Lösungen hier überprüfen http://css-tricks.com/fluid-width-equal-height-columns/


Ich habe keine Ahnung warum diese Arbeit, aber sie löst mein Problem wie ein Zauber. Vielen Dank
Kombinieren Sie

Funktioniert auch bei mir. Auch wenn es nicht der saubere Weg ist. Vielen Dank!
Mark Anthony Uy

17
Hacky wie die Hölle. Ich empfehle dies nicht für eine Produktionsanwendung
FedericoCapaldo

Das ist unglaublich, haha. Ich dachte nicht, dass dies tatsächlich funktionieren würde
Tom McDonough

11

Bitte setzen Sie parent div auf, overflow: hidden
dann können Sie in child divs einen großen Betrag für padding-bottom einstellen. Zum Beispiel werden
padding-bottom: 5000px
dann margin-bottom: -5000px
und dann alle untergeordneten Divs die Größe des Elternteils sein.
Dies funktioniert natürlich nicht, wenn Sie versuchen, Inhalte in das übergeordnete Div einzufügen (dh außerhalb anderer Divs).

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

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


scheint ein bisschen schmutzig, hat aber für mich funktioniert - die einzige Lösung für diese Frage. Ich habe dies mit Twitter Bootstrap versucht.
Cukabeka

8

Hat der Elternteil eine Größe? Wenn Sie die Größe der Eltern so einstellen.

div.parent { height: 300px };

Dann können Sie das Kind so auf die volle Höhe strecken lassen.

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

BEARBEITEN

So würden Sie es mit JavaScript machen.


Eltern haben keine feste Höhe. Es dehnt sich entsprechend der linken Größe des Kindes aus.
Veera

Ah, das habe ich mir gedacht, dann brauchst du etwas JavaScript, ich werde es gleich anhängen.
Olical

@Olical JSFiddle Link ist defekt. Entweder entfernen oder die Antwort aktualisieren. Vielen Dank!
itsmysterybox

1
Der Link zu js gibt jetzt eine 404
Chanoch

5

Die Anzeige von CSS-Tabellen ist dafür ideal:

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

Ursprüngliche Antwort (vorausgesetzt, jede Spalte könnte größer sein):

Sie versuchen, die Größe der Eltern von der Größe der Kinder und die Größe der Kinder von der Größe der Eltern abhängig zu machen. Wird nicht berechnet. CSS Faux-Spalten sind die beste Lösung. Es gibt mehr als einen Weg, dies zu tun. Ich würde lieber kein JavaScript verwenden.


Guter Punkt. Wie wäre es, wenn die Größe der Kinder von der Größe des größten Geschwisters abhängt (ob dies durch die Größe des Elternteils bestimmt wird oder nicht) und nicht vom Elternteil? Ich denke, das geht in CSS nicht.
Mikato

Nein, Geschwister können die Größe der anderen nicht beeinflussen. Das display: table+ display: table-cellLayout erzeugt jedoch das gewünschte Ergebnis.
Salman A

Tolles Update! Am Ende habe ich dies jedoch versucht und wollte eine Leerzeichen-Trennung zwischen den Divs / Zellen und musste schließlich innere Divs innerhalb der Tabellenzellen-Divs erstellen, um dies zu erreichen, und verlor dann natürlich die Fähigkeit, sie dazu zu bringen, die volle Höhe zu nutzen weil die inneren Divs keine Tabellenzellen-Divs waren - genau das gleiche Problem. Irgendwelche Ideen dafür? Art fehlender Zellabstand jetzt.
Mikato

Ah, in CSS gibt es Randabstände! stackoverflow.com/questions/339923/… Ich konnte meine tabellenähnlichen Divs mithilfe von Randabständen gut mit Leerzeichen trennen. Ich habe jetzt die Möglichkeit, Tabellenzellen (farbige Hintergrundblöcke) durch geschickte Verwendung der Tabellenzellen-Divs dazu zu bringen, die volle Höhe des übergeordneten Elements zu nutzen oder nicht.
Mikato

Nur ein Gotcha, auf das ich gestoßen bin: Sie können dies nicht verwenden mit float: stackoverflow.com/questions/20110217/…
Joshua Pinter

4

Ich habe dies kürzlich auf meiner Website mit jQuery getan. Der Code berechnet die Höhe des höchsten Divs und setzt die anderen Divs auf die gleiche Höhe. Hier ist die Technik:

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

Ich glaube nicht, dass height:100%es funktionieren wird. Wenn Sie also die Div-Höhen nicht explizit kennen, gibt es meiner Meinung nach keine reine CSS-Lösung.


1
Sie sollten dies mindestens bei Bereitschaft, Größenänderung, Orientierungsänderung und Schriftgrößenänderung auslösen.
netAction

4

Ich habe dies für einen Kommentarbereich verwendet:

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

Sie könnten das Kind rechts nach rechts schweben lassen, aber in diesem Fall habe ich die Breiten jedes Div genau berechnet.


1
Das erste, was mir in den Sinn kam, war die Größe: Ich erbe nicht sicher, warum niemand gestimmt hat
Andreas

3

Wenn Sie Bootstrap kennen, können Sie dies einfach mithilfe der Eigenschaft 'flex' tun. Sie müssen lediglich die folgenden CSS-Eigenschaften an das übergeordnete div übergeben

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

wo .homepageSectionist mein eltern div. Fügen Sie nun untergeordnetes div in Ihr HTML als

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

Dabei ist abc mein Kind div. Sie können die Gleichheit der Körpergröße in beiden Kindern unabhängig von der Grenze überprüfen, indem Sie dem Kind div eine Grenze geben


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>

Ich habe den Inline-Stil verwendet, um eine Idee zu geben.


-2

Ich habe in einem Praktikumsinterview von diesem tollen Trick erfahren. Die ursprüngliche Frage lautet, wie Sie sicherstellen können, dass die Höhe jeder oberen Komponente in drei Spalten dieselbe Höhe hat, in der der gesamte verfügbare Inhalt angezeigt wird. Erstellen Sie grundsätzlich eine unsichtbare untergeordnete Komponente, die die maximal mögliche Höhe darstellt.

<div class="parent">
    <div class="assert-height invisible">
        <!-- content -->
    </div>
    <div class="shown">
        <!-- content -->
    </div>
</div>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.