Stellen Sie sicher, dass div (Höhe) die verbleibende Höhe des Elternteils belegt

107

http://jsfiddle.net/S8g4E/

Ich habe einen Container divmit zwei Kindern. Das erste Kind hat eine bestimmte Größe. Wie kann ich das zweite Kind dazu bringen, den "freien Platz" des Containers zu belegen, divohne eine bestimmte Höhe anzugeben?

Im Beispiel sollte das Rosa divauch den weißen Raum einnehmen.


Ähnlich wie bei dieser Frage: Wie kann man div dazu bringen, die verbleibende Höhe einzunehmen?

Aber ich möchte keine absolute Position geben .

Alvaro
quelle
Ich habe versucht, dem zweiten Kind eine Körpergröße von 100% zu geben, aber es funktioniert nicht: jsfiddle.net/S8g4E/1
Alvaro

Antworten:

156

Das Erweitern des untergeordneten Elements #down, um den verbleibenden Speicherplatz zu füllen, #containerkann auf verschiedene Arten erfolgen, je nachdem, welche Browserunterstützung Sie erreichen möchten und ob #upeine definierte Höhe vorliegt oder nicht .

Proben

Gitter

Das gridLayout von CSS bietet eine weitere Option, die jedoch möglicherweise nicht so einfach ist wie das Flexbox-Modell. Es ist jedoch nur das Styling des Containerelements erforderlich:

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

Das grid-template-rowsdefiniert die erste Zeile als feste Höhe von 100 Pixel, und die verbleibenden Zeilen werden automatisch gedehnt, um den verbleibenden Platz auszufüllen.

Ich bin mir ziemlich sicher, dass IE11 -ms-Präfixe erfordert. Überprüfen Sie daher die Funktionalität in den Browsern, die Sie unterstützen möchten.

Flexbox

Das Flexible Box Layout Module ( flexbox) von CSS3 wird jetzt gut unterstützt und kann sehr einfach implementiert werden. Da es flexibel ist, funktioniert es auch, wenn #upkeine Höhe definiert ist.

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

Es ist wichtig zu beachten, dass die IE10- und IE11-Unterstützung für einige Flexbox-Eigenschaften fehlerhaft sein kann und IE9 oder niedriger überhaupt keine Unterstützung bietet.

Berechnete Höhe

Eine andere einfache Lösung besteht darin, die CSS3-calc Funktionseinheit zu verwenden, wie Alvaro in seiner Antwort hervorhebt. Die Größe des ersten Kindes muss jedoch ein bekannter Wert sein:

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

Es wird ziemlich häufig unterstützt, mit den einzigen bemerkenswerten Ausnahmen <= IE8 oder Safari 5 (keine Unterstützung) und IE9 (teilweise Unterstützung). Einige andere Probleme umfassen die Verwendung von calc in Verbindung mit Transformation oder Box-Shadow. Testen Sie daher unbedingt in mehreren Browsern, ob dies für Sie von Belang ist.

Andere Alternativen

Wenn ältere Unterstützung benötigt wird, können Sie hinzufügen height:100%;, #downdass das rosa Div mit einer Einschränkung die volle Höhe erreicht. Dies führt zu einem Überlauf des Behälters, da #updieser nach unten gedrückt wird.

Daher können Sie overflow: hidden;dem Container etwas hinzufügen, um dies zu beheben.

Wenn die Höhe von #upfestgelegt ist, können Sie sie auch absolut innerhalb des Behälters positionieren und eine Polsterplatte hinzufügen #down.

Eine weitere Option wäre die Verwendung einer Tabellenanzeige:

#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;}​
Benutzer
quelle
4
Ich möchte, dass #down #container height - #up height hat. Überlauf versteckt ist also nicht das, wonach ich suche. Und möchte auch keine absolute Position verwenden. Vielen Dank!
Alvaro
@Alvaro, ich habe eine weitere Option hinzugefügt, die Tabellenanzeigen verwendet. Nachteil ist hier die Kompatibilität. PS Ein Element, das absolut in einem Container position: relative;positioniert ist und sich relativ zum Container und nicht zum Fenster befindet. Das sollte also eine praktikable Option sein.
Benutzer
2
Die Tabellenzeile sollte für Sie funktionieren . Weitere Informationen finden Sie in dieser jsFiddle . Die absolute Positionsmethode kann nicht die gleichen Ergebnisse wie diese Geige liefern, daher können wir diese von der Liste streichen (#down und #container haben in diesem Szenario die gleiche Höhe).
Benutzer
3
Du fragst viel, @Alvaro. CSS ist keine Skriptsprache. es kann nichts berechnen. Sie stecken entweder in Illusionen oder in js.
Jezen Thomas
1
@Quantastical, danke für deine Hilfe, aber in deiner letzten Bearbeitung hast du gerade die Antwort kopiert, die ich gepostet habe. Einige Erwähnungen wären zumindest nett.
Alvaro
24

Es ist fast zwei Jahre her, seit ich diese Frage gestellt habe. Ich habe mir gerade css calc () ausgedacht, das dieses Problem behebt, und dachte, es wäre schön, es hinzuzufügen, falls jemand das gleiche Problem hat. (Übrigens habe ich letztendlich die Position absolut verwendet).

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

Hier ist die CSS

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

Weitere Informationen dazu finden Sie hier: http://css-tricks.com/a-couple-of-use-cases-for-calc/

Browserunterstützung: http://caniuse.com/#feat=calc

Alvaro
quelle
1
Ich habe auch CSS3s verwendet, bei calcdenen eine breite Browserunterstützung nicht so wichtig ist (IE8 und darunter und Safari 5 unterstützen sie nicht).
Benutzer
3
Gibt es eine Möglichkeit, mit einer dynamischen #upHöhe Ähnliches zu tun ?
Adam Waite
@AdamWaite, mit einer dynamischen # up-Höhe möchten Sie die in der anderen Antwort beschriebene Überlauflösung verwenden.
Benutzer
5

Meine Antwort verwendet nur CSS und keinen Überlauf: versteckt oder angezeigt: Tabellenzeile. Es erfordert, dass das erste Kind wirklich eine bestimmte Größe hat, aber in Ihrer Frage geben Sie an, dass nur die Größe des zweiten Kindes nicht angegeben werden muss. Ich glaube, Sie sollten dies für akzeptabel halten.

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/

TWR Cole
quelle
2

Überprüfen Sie die Demo - http://jsfiddle.net/S8g4E/6/

benutze CSS -

#container { width: 300px; height: 300px; border:1px solid red; display: table;}
#up { background: green; display: table-row; }
#down { background:pink; display: table-row;}
Dipak
quelle
Sie sollten hinzufügen height: 1px, #upum sicherzustellen, dass die Mindesthöhe erreicht wird. Hier ist die Browser-Unterstützung für display: table: caniuse.com/css-table
dreißig Punkte
Könnten Sie mir bitte zeigen, wie diese Lösung in diesem "komplexeren" Beispiel erreicht werden kann ? Jsfiddle.net/fyNX4 Vielen Dank
Alvaro
2

Es sei denn , ich bin Missverständnis, können Sie einfach hinzufügen height: 100%;und overflow:hidden;zu #down.

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

Live DEMO

Bearbeiten: Da Sie nicht verwenden möchten overflow:hidden;, können Sie display: table;für dieses Szenario verwenden; Es wird jedoch vor IE 8 nicht unterstützt. ( display: table;Unterstützung )

#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;
}​

Live DEMO

Hinweis: Sie haben gesagt, dass die #downHöhe #containerHöhe minus #upHöhe sein soll. Die display:table;Lösung macht genau das und diese jsfiddle wird das ziemlich klar darstellen.

Josh Mein
quelle
1
Ich möchte nicht, dass #down die Höhe des Containers überschreitet
Alvaro
Das habe ich gerade bemerkt. Sie können hinzufügen overflow:hidden, um den zusätzlichen Inhalt auszublenden.
Josh Mein
1
Ich kopiere / füge ein, was ich zu MrSlayer gesagt habe: Ich möchte, dass #down #container height - #up height hat. Überlauf versteckt ist also nicht das, wonach ich suche. Und möchte auch keine absolute Position verwenden. Vielen Dank!
Alvaro
Das Problem dabei ist, dass, wenn Sie die beiden Divs in Ihrem Beispiel zurücksetzen, das grüne Div außerhalb liegt.
Ced
Dies beantwortet die Frage überhaupt nicht. Es heißt "Um die gesamte verbleibende Höhe zu besetzen", obwohl dies die gesamte verbleibende Höhe einnimmt, kommt es zu einem Überlauf.
Giridhar Karnik
1

Sie können Floats verwenden, um Inhalte nach unten zu verschieben:

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

Sie haben einen Container mit fester Größe:

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

Der Inhalt darf neben einem Float fließen. Es sei denn, wir stellen den Schwimmer auf volle Breite ein:

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

Während #upund #downteilen Sie die obere Position, #downkann der Inhalt erst nach dem unteren Rand des Floats beginnen #up:

#down {
    height:100%;
}​
biziclop
quelle
Beachten Sie, dass #uptatsächlich der obere Teil von #down: jsfiddle.net/thirtydot/S8g4E/9
dreißigdot
Ja, so funktioniert es. Aber wenn OP keinen abgerundeten Rand oder etwas anderes braucht #up, ist es wahrscheinlich akzeptabel.
Biziclop
Diese Lösung ist nah, aber ich möchte, dass #down #container height - #up height hat. (In Ihrer Lösung #down height = #container height). Danke '
Alvaro
1
@Alvaro: Warum muss es so sein? Diese Lösung sieht in den meisten Fällen korrekt aus, auch wenn es sich nur um eine Illusion handelt.
30.
Nun, diese Frage ist ein vereinfachtes Beispiel aus diesem "komplexeren" Beispiel: jsfiddle.net/fyNX4 Es würde nicht funktionieren, nein?
Alvaro
1

Abstrakt

Ich fand keine zufriedenstellende Antwort, also musste ich es selbst herausfinden.

Meine Anforderungen:

  • das Element sollte nehmen genau den verbleibenden Platz , wenn entweder seine Inhaltsgröße ist kleiner oder größer ist als die verbleibende Raum Größe (im zweiten Fall scrollbar sollte gezeigt werden );
  • Die Lösung sollte funktionieren, wenn die übergeordnete Höhe berechnet und nicht angegeben wird .
  • calc()sollte nicht verwendet werden, da das verbleibende Element nichts über andere Elementgrößen wissen sollte ;
  • Es sollten moderne und vertraute Layouttechniken wie Flexboxen verwendet werden.

Die Lösung

  • Verwandeln Sie alle direkten Eltern mit berechneter Größe (falls vorhanden) und die nächsten Eltern, deren Größe angegeben ist , in Flexboxen .
  • Angeben , flex-grow: 1zu allen direkt Eltern mit berechneter Höhe (falls vorhanden) und das Elemente , so dass sie alle verbleibenden Platz , wenn das Element Inhaltsgröße kleiner wird dauern;
  • Geben Sie flex-shrink: 0für alle Flex-Elemente mit fester Höhe an , damit sie nicht werden wird kleiner , wenn der Elementinhalt Größe ist größer als die verbleibende Raumgröße;
  • Geben Sie overflow: hiddenan, dass alle direkten Eltern mit berechneter Höhe (falls vorhanden) das Scrollen deaktivieren und die Anzeige von Überlaufinhalten verbieten sollen.
  • Angeben , overflow: autozu dem Element zu ermöglichen , im Inneren zu scrollen.

JSFiddle (Element hat direkte Eltern mit berechneter Höhe)

JSFiddle (einfacher Fall: keine direkten Eltern mit berechneter Größe)

N. Kudryavtsev
quelle
-3

Ich bin mir nicht sicher, ob dies nur mit CSS möglich ist, es sei denn, Sie täuschen es gerne mit Illusionen vor. Verwenden Sie vielleicht die Antwort von Josh Mein und setzen Sie #containerauf overflow:hidden.

Für das, was es wert ist, ist hier eine jQuery-Lösung:

var contH = $('#container').height(),
upH = $('#up').height();
$('#down').css('height' , contH - upH);
Jezen Thomas
quelle
Danke, ich habe nach einer reinen CSS-Lösung gesucht.
Alvaro