Erweitern Sie ein div, um die verbleibende Breite zu füllen


552

Ich möchte ein zweispaltiges Div-Layout, bei dem jedes eine variable Breite haben kann, z

div {
  float: left;
}

.second {
  background: #ccc;
}
<div>Tree</div>
<div class="second">View</div>

Ich möchte, dass das 'view'-Div auf die gesamte verfügbare Breite erweitert wird, nachdem das' tree'-Div den benötigten Platz gefüllt hat.

Derzeit wird die Größe meines 'view'-Div auf den Inhalt geändert, den es enthält. Es ist auch gut, wenn beide Divs die gesamte Höhe einnehmen.


Haftungsausschluss nicht doppelt:



1
Entweder verstehe ich die Frage nicht oder ich verstehe nicht, wie Sie die akzeptierte Antwort wählen, da dort sowohl Breiten als auch Höhen mit der Unannehmlichkeit vonoverflow hidden
user10089632

Antworten:


1013

Die Lösung dieses Problems ist eigentlich sehr einfach, aber nicht bei allen offensichtlich. Sie müssen einen sogenannten "Block Formatierungskontext" (BFC) auslösen, der auf bestimmte Weise mit Floats interagiert.

Nehmen Sie einfach das zweite Div, entfernen Sie den Schwimmer und geben Sie ihn overflow:hiddenstattdessen. Jeder andere als der sichtbare Überlaufwert macht den Block, auf den er gesetzt ist, zu einem BFC. BFCs erlauben weder Nachkommen-Floats, ihnen zu entkommen, noch erlauben sie Geschwister- / Ahnen-Floats, in sie einzudringen. Der Nettoeffekt hier ist, dass das schwebende Div seine Sache macht, dann wird das zweite Div ein gewöhnlicher Block sein, der die gesamte verfügbare Breite außer der vom Float belegten einnimmt .

Dies sollte in allen aktuellen Browsern funktionieren, obwohl Sie möglicherweise hasLayout in IE6 und 7 auslösen müssen. Ich kann mich nicht erinnern.

Demos:


28
Hervorragende Antwort! Sie liegen jedoch falsch, wenn Sie sagen, dass "ein anderer Überlaufwert als auto" einen BFC ergibt. Was Sie meinen, ist, dass jeder andere Überlaufwert als der Standardwert (sichtbar) ihn zu einem BFC macht. Tatsächlich funktioniert Overflow Auto auch perfekt - das würde ich empfehlen (nur für den Fall, dass Sie relativ positionierte Elemente haben, die aus diesem Div herausschauen könnten).
BT

52
Dieser Artikel hat eine schöne Erklärung: colinaarts.com/articles/the-magic-of-overflow-hidden
Max Cantor

1
Was ist, wenn der Inhalt groß genug ist, um das Div zu überlaufen?
Giannis Christofakis

11
Es ist wichtig zu beachten, dass die Reihenfolge der Kinder wichtig ist. Das schwebende Element mit fester Breite muss über dem anderen liegen. Ich habe zu lange gebraucht, um herauszufinden, warum es bei mir mit geänderter Reihenfolge nicht funktioniert hat.
Riplexus

2
Ich habe eine Antwort geschrieben, in der erklärt wird, warum ein nicht sichtbarer Überlauf aller Dinge einen BFC auslöst, basierend auf den Antworten von David und Boris, die hier zu finden sind: stackoverflow.com/questions/9943503/… War meine Interpretation korrekt?
BoltClock

104

Ich habe gerade die Magie der Flexboxen entdeckt (Anzeige: Flex). Versuche dies:

<style>
  #box {
    display: flex;
  }
  #b {
    flex-grow: 100;
    border: 1px solid green;
  }
</style>
<div id='box'>
 <div id='a'>Tree</div>
 <div id='b'>View</div>
</div>

Flexboxen geben mir die Kontrolle, die ich mir seit 15 Jahren gewünscht habe. Es ist endlich da! Weitere Informationen: https://css-tricks.com/snippets/css/a-guide-to-flexbox/


Ich weiß nicht, was Sie entdeckt haben, aber Ihr Code funktioniert nicht in der neuesten Chrome jsfiddle.net/fjb548kw/3
Yevgeniy

@YevgeniyAfanasyev Ich habe das "float: left;" um das Problem zu beheben. Danke für den Hinweis!
BT

Vielen Dank. Können Sie mir bitte erklären , warum haben Sie flex-grow: 100;statt flex-grow: 1;?
Jewgenij Afanasjew

2
@YevgeniyAfanasyev Kein besonderer Grund, außer so mache ich es gerne. Es erlaubt mir, in Prozent zu denken. Wenn ich also so etwas wie #a setzen flex-grow:10und dann #b setzen könnte, flex-grow: 90würde #a 10% der Linienbreite und #b 90% der Linienbreite betragen. Wenn keine anderen Elemente einen flexiblen Breitenstil haben, spielt es technisch keine Rolle, was Sie eingeben.
BT

Dies funktionierte am besten für mich, als ich versuchte, einen Eingang und eine Schaltfläche nebeneinander zu platzieren, als wären sie eins.
Souleste

28

Flexbox-Lösung

Dafür ist die flex-growImmobilie da.

html, body {
  height: 100%;
}
body {
  display: flex;
}
.second {
  flex-grow: 1;
}
<div style="background: #bef;">Tree</div>
<div class="second" style="background: #ff9;">View</div>

Hinweis: Fügen Sie bei Bedarf von Ihren unterstützten Browsern Präfixe für Flex-Anbieter hinzu .


27

Dies wäre ein gutes Beispiel für etwas, das mit Tabellen trivial und mit CSS schwer (wenn nicht unmöglich, zumindest im Sinne eines Cross-Browsers) zu tun hat.

Wenn beide Spalten eine feste Breite hätten, wäre dies einfach.

Wenn eine der Spalten eine feste Breite hätte, wäre dies etwas schwieriger, aber durchaus machbar.

Wenn beide Spalten eine variable Breite haben, müssen Sie meiner Meinung nach nur eine zweispaltige Tabelle verwenden.


11
Die Tabelle ist in einem reaktionsschnellen Design nicht sehr gut, bei dem die rechte Spalte bei kleinen Geräten unter die linke gleiten soll.
S ..

1
Es gibt einige reaktionsschnelle
Rikki

Ich neige jetzt dazu, häufig zwei separate Layouts vollständig zu entwerfen und mithilfe von Medienabfragen auf einem Mobiltelefon zu ändern. display:none;Während ich auf einer verschiebbaren Skala so viel wie möglich zu 100% reagiere, ist es manchmal besser, Ihr Design vollständig zu ändern, damit ein Mobiltelefon das Touchscreen-Gefühl nutzt und Schaltflächenstil.
Bysander

22

Überprüfen Sie diese Lösung

.container {
  width: 100%;
  height: 200px;
  background-color: green;
}
.sidebar {
  float: left;
  width: 200px;
  height: 200px;
  background-color: yellow;
}
.content {
  background-color: red;
  height: 200px;
  width: auto;
  margin-left: 200px;
}
.item {
  width: 25%;
  background-color: blue;
  float: left;
  color: white;
}
.clearfix {
  clear: both;
}
<div class="container">
  <div class="clearfix"></div>
  <div class="sidebar">width: 200px</div>

  <div class="content">
    <div class="item">25%</div>
    <div class="item">25%</div>
    <div class="item">25%</div>
    <div class="item">25%</div>
  </div>
</div>


2
Dies ist im Allgemeinen eine überlegene Lösung, da ein Ausblenden des Überlaufs nicht immer erwünscht ist.
Joseph Lennox

3
Per OP: "Ich möchte ein zweispaltiges Div-Layout, bei dem jedes eine variable Breite haben kann." In Ihrer Antwort müssen Sie die Breite der ersten Spalte kennen, damit sie nicht variabel ist. Sie können auch feste Breiten für beide Spalten festlegen und diese einfach schweben lassen.
Jacob Alvarez

17

Verwendung calc:

.leftSide {
  float: left;
  width: 50px;
  background-color: green;
}
.rightSide {
  float: left;
  width: calc(100% - 50px);
  background-color: red;
}
<div style="width:200px">
  <div class="leftSide">a</div>
  <div class="rightSide">b</div>
</div>

Das Problem dabei ist, dass alle Breiten explizit definiert werden müssen, entweder als Wert (px und em funktionieren einwandfrei) oder als Prozentsatz von etwas, das explizit selbst definiert wurde.


15

Hier könnte dies helfen ...

<html>

<head>
  <style type="text/css">
    div.box {
      background: #EEE;
      height: 100px;
      width: 500px;
    }
    div.left {
      background: #999;
      float: left;
      height: 100%;
      width: auto;
    }
    div.right {
      background: #666;
      height: 100%;
    }
    div.clear {
      clear: both;
      height: 1px;
      overflow: hidden;
      font-size: 0pt;
      margin-top: -1px;
    }
  </style>
</head>

<body>
  <div class="box">
    <div class="left">Tree</div>
    <div class="right">View</div>
    <div class="clear" />
  </div>
</body>

</html>


+1, weil Ihr Beispiel zu funktionieren scheint, aber in meinem realen Szenario kann es sein, dass einige Inhalte aus 'view' in 'tree' div kriechen, da tree div nicht 100% ist, dass Javascript es zwingt, klein und nach der Höhe des Baums zu sein Ich sehe Inhalte
anzeigen

In diesem Fall können Sie, wenn Sie die maximale Breite der linken Spalte kennen, entweder einen Stil für die maximale Breite angeben (funktioniert im IE nicht) oder an den Rand links denken (Vorsicht vor Fehlern mit doppeltem Rand im IE) oder Polsterung links.
a6hi5h3k

Das war großartig! Ich benutze es <div class="clear" style="clear: both; height: 1px; overflow: hidden; font-size:0pt; margin-top: -1px;"></div>
inline

5

Ich verstehe nicht, warum die Leute bereit sind, so hart zu arbeiten, um eine reine CSS-Lösung für einfache Spaltenlayouts zu finden, die mit dem alten TABLETag SO EINFACH sind .

Alle Browser haben immer noch die Logik des Tabellenlayouts ... Nennen Sie mich vielleicht einen Dinosaurier, aber ich sage, lassen Sie es Ihnen helfen.

<table WIDTH=100% border=0 cellspacing=0 cellpadding=2>
  <tr>
    <td WIDTH="1" NOWRAP bgcolor="#E0E0E0">Tree</td>
    <td bgcolor="#F0F0F0">View</td>
  </tr>
</table>

Auch in Bezug auf die Cross-Browser-Kompatibilität viel weniger riskant.


2
ja, aber wenn alles von css gemacht wird, warum nicht das, zumindest eine neugier, wenn es möglich ist?
Anurag Uniyal

2
Dies liegt daran media-queries, dass es mit dem alten tableTag unmöglich ist, beide Spalten in kleinen Geräten übereinander zu platzieren . Damit dies funktioniert, müssen Sie CSSTabellenstile anwenden . Daher ist es heutzutage besser, dies zu lösen, CSSwenn Sie ein ansprechendes Layout für jede Bildschirmgröße wünschen.
ElChiniNet

5

Wenn die Breite der anderen Spalte festgelegt ist, können Sie die calcCSS-Funktion für alle gängigen Browser verwenden :

width: calc(100% - 20px) /* 20px being the first column's width */

Auf diese Weise wird die Breite der zweiten Reihe berechnet (dh die verbleibende Breite) und entsprechend angewendet.


Dies ist die beste Antwort, wenn Sie etwas anderes als Flexbox verwenden, wie zum Beispiel css-grid. Funktioniert auch damit position: fixed, was es rundum zur perfekten Wahl macht! Vielen Dank!
Bartekus

3

<html>

<head>
  <style type="text/css">
    div.box {
      background: #EEE;
      height: 100px;
      width: 500px;
    }
    div.left {
      background: #999;
      float: left;
      height: 100%;
      width: auto;
    }
    div.right {
      background: #666;
      height: 100%;
    }
    div.clear {
      clear: both;
      height: 1px;
      overflow: hidden;
      font-size: 0pt;
      margin-top: -1px;
    }
  </style>
</head>

<body>
  <div class="box">
    <div class="left">Tree</div>
    <div class="right">View</div>
    <div class="right">View</div>
    <div style="width: <=100% getTreeWidth()100 %>">Tree</div>
    <div class="clear" />
  </div>
  <div class="ColumnWrapper">
    <div class="Colum­nOne­Half">Tree</div>
    <div class="Colum­nOne­Half">View</div>
  </div>

</body>

</html>


Ich möchte so etwas wie eine Statusleiste mit festen Elementen links, festen Elementen rechts und einer Nachrichtenzeile, die den gesamten verbleibenden Platz belegt. Ich begann mit dieser Antwort und fügte meine Nachricht div NACH den Floats hinzu mit: height: 20px; Leerraum: Nowrap; Überlauf versteckt; Textüberlauf: Clip
Englebart

3

Sie können CSS Grid Layout ausprobieren .

dl {
  display: grid;
  grid-template-columns: max-content auto;
}

dt {
  grid-column: 1;
}

dd {
  grid-column: 2;
  margin: 0;
  background-color: #ccc;
}
<dl>
  <dt>lorem ipsum</dt>
  <dd>dolor sit amet</dd>
  <dt>carpe</dt>
  <dd>diem</dd>
</dl>


2

Flex-Grow - Dies definiert die Fähigkeit eines Flex-Elements, bei Bedarf zu wachsen. Es akzeptiert einen Wert ohne Einheit, der als Anteil dient. Es bestimmt, wie viel Platz im Flex-Container der Artikel einnehmen soll.

Wenn für alle Elemente Flex-Grow auf 1 gesetzt ist, wird der verbleibende Platz im Container gleichmäßig auf alle untergeordneten Elemente verteilt. Wenn eines der Kinder den Wert 2 hat, nimmt der verbleibende Speicherplatz doppelt so viel Speicherplatz ein wie die anderen (oder es wird zumindest versucht). Sehen Sie hier mehr

.parent {
  display: flex;
}

.child {
  flex-grow: 1; // It accepts a unitless value that serves as a proportion
}

.left {
  background: red;
}

.right {
  background: green;
}
<div class="parent"> 
  <div class="child left">
      Left 50%
  </div>
   <div class="child right">
      Right 50%
  </div>
</div>


1

Eine etwas andere Implementierung,

Zwei Div-Panels (Inhalt + Extra) nebeneinander werden content panelerweitert, wennextra panel nicht vorhanden sind.

jsfiddle: http://jsfiddle.net/qLTMf/1722/


1

Pat - Du hast recht. Deshalb würde diese Lösung sowohl "Dinosaurier" als auch Zeitgenossen zufriedenstellen. :) :)

.btnCont {
  display: table-layout;
  width: 500px;
}

.txtCont {
  display: table-cell;
  width: 70%;
  max-width: 80%;
  min-width: 20%;
}

.subCont {
  display: table-cell;
  width: 30%;
  max-width: 80%;
  min-width: 20%;
}
<div class="btnCont">
  <div class="txtCont">
    Long text that will auto adjust as it grows. The best part is that the width of the container would not go beyond 500px!
  </div>
  <div class="subCont">
    This column as well as the entire container works like a table. Isn't Amazing!!!
  </div>
</div>


2
Es gibt keine HTML-Referenz für die CSS-Klasse .ip und es funktioniert nicht in IE7
Keith K

1

Sie können die CSS-Bibliothek von W3 verwenden, die eine Klasse mit dem Namen enthält rest, die genau das tut:

<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">

<div class="w3-row">
  <div class="w3-col " style="width:150px">
    <p>150px</p>
  </div>
  <div class="w3-rest w3-green">
    <p>w3-rest</p>
  </div>
</div>

Vergessen Sie nicht, die CSS-Bibliothek auf den folgenden Seiten zu verknüpfen header:

<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">

Hier ist die offizielle Demo: W3 School Tryit Editor


Sieht so aus, als würde nur "Überlauf: versteckt"
hinzugefügt

0

Ich bin mir nicht sicher, ob dies die Antwort ist, die Sie erwarten, aber warum setzen Sie die Breite von Tree nicht auf 'auto' und die Breite von 'View' auf 100%?


3
Weil dadurch der zweite Schwimmer unter den ersten fällt, weil er zu breit ist.
Cletus

0

Schauen Sie sich die verfügbaren CSS-Layout-Frameworks an. Ich würde Simpl oder das etwas komplexere Blueprint-Framework empfehlen .

Wenn Sie Simpl verwenden (bei dem nur eine simpl.css- Datei importiert wird ), können Sie Folgendes tun:

<div class="Colum­nOne­Half">Tree</div>
<div class="Colum­nOne­Half">View</div>

für ein 50-50-Layout oder:

<div class="Colum­nOne­Quarter">Tree</div>
<div class="Colum­nThreeQuarters">View</div>

für einen 25-75.

So einfach ist das.


Werden beide Spalten eine variable Breite haben?
Anurag Uniyal

0

Danke für den Plug von Simpl.css!

Denken Sie daran, alle Ihre Spalten ColumnWrapperso einzuschließen.

<div class="ColumnWrapper">
    <div class="Colum­nOne­Half">Tree</div>
    <div class="Colum­nOne­Half">View</div>
</div>

Ich bin im Begriff, Version 1.0 von Simpl.css zu veröffentlichen, also helfen Sie, das Wort zu verbreiten!


0

Ich habe eine Javascript-Funktion geschrieben, die ich von jQuery $ (document) .ready () aus aufrufe. Dadurch werden alle untergeordneten Elemente des übergeordneten div analysiert und nur das am weitesten rechts stehende untergeordnete Element aktualisiert.

html

...
<div class="stretch">
<div style="padding-left: 5px; padding-right: 5px; display: inline-block;">Some text
</div>
<div class="underline" style="display: inline-block;">Some other text
</div>
</div>
....

Javascript

$(document).ready(function(){
    stretchDivs();
});

function stretchDivs() {
    // loop thru each <div> that has class='stretch'
    $("div.stretch").each(function(){
        // get the inner width of this <div> that has class='stretch'
        var totalW = parseInt($(this).css("width"));
        // loop thru each child node
        $(this).children().each(function(){
            // subtract the margins, borders and padding
            totalW -= (parseInt($(this).css("margin-left")) 
                     + parseInt($(this).css("border-left-width")) 
                     + parseInt($(this).css("padding-left"))
                     + parseInt($(this).css("margin-right")) 
                     + parseInt($(this).css("border-right-width")) 
                     + parseInt($(this).css("padding-right")));
            // if this is the last child, we can set its width
            if ($(this).is(":last-child")) {
                $(this).css("width","" + (totalW - 1 /* fudge factor */) + "px");
            } else {
                // this is not the last child, so subtract its width too
                totalW -= parseInt($(this).css("width"));
            }
        });
    });
}

0

Dies ist mit Flexbox ziemlich einfach. Siehe den Ausschnitt unten. Ich habe einen Wrapper-Container hinzugefügt, um den Fluss zu steuern und eine globale Höhe festzulegen. Es wurden auch Rahmen hinzugefügt, um die Elemente zu identifizieren. Beachten Sie, dass Divs jetzt bei Bedarf auch auf die volle Höhe erweitert werden. Herstellerpräfixe sollten in einem realen Szenario für Flexbox verwendet werden, da dies noch nicht vollständig unterstützt wird.

Ich habe ein kostenloses Tool entwickelt, um Layouts mithilfe von Flexbox zu verstehen und zu entwerfen. Überprüfen Sie es hier: http://algid.com/Flex-Designer

.container{
    height:180px;
    border:3px solid #00f;
    display:flex;
    align-items:stretch;
}
div {
    display:flex;
    border:3px solid #0f0;
}
.second {
    display:flex;
    flex-grow:1;
    border:3px solid #f00;
}
<div class="container">
    <div>Tree</div>
    <div class="second">View</div>
</div>


Haben Sie ALLE vorherigen Antworten gelesen, bevor Sie Ihre hinzugefügt haben? es scheint nein ...
Temani Afif

Als Randnotiz müssen Sie nicht hinzufügen, stretchda dies der Standardwert ist und display:flexder
untergeordnete

Ich frage mich, warum die Abstimmung ohne Kommentar. Beantwortet diese Antwort nicht die Frage? Warum? Wenn anderen zu helfen versuchen , wird bestraft ich zweimal , bevor meine nächste Antwort denken,
Mario Vázquez

1
Sie haben zwei Kommentare nach der Abstimmung erhalten, ist es nicht genug?
Temani Afif

Temari, hast du mein Tool überprüft? Findest du das nicht nützlich und könntest anderen helfen? Denken Sie, dass dies nicht mit der Frage zusammenhängt? Wo ist Ihre Antwort auf diese Frage? Ich kann es nicht sehen Was ist deine Rolle hier?
Mario Vázquez

-3

Wenn beide Breiten variabel sind, warum berechnen Sie die Breite nicht mit Skripten oder Serverseiten?

<div style="width: <=% getTreeWidth() %>">Tree</div>

<div style="width: <=% getViewWidth() %>">View</div>

3
Woher weiß der Server, wie die Layout-Engine des Clients funktioniert?
Kev

Einfach: Entwickeln Sie es für 90% der Browser da draußen :) IE 7+, FF3 + und Safari unterstützen CSS 3. Sie können auch das Standardelement IE6 <! - [wenn IE 6]> einschließen. Übrigens, welcher Browser unterstützt style = "width:%" nicht?
Amischiefr

Ich weiß nicht, wie es serverseitig gemacht werden kann, aber ja, einige Javscript können es tun, aber ich möchte es vermeiden, es sei denn, CSS / HTML kann es nicht
Anurag Uniyal

Was es nicht kann. Wenn Sie also möchten, dass beide dynamisch sind, müssen Sie dies entweder skript- oder serverseitig tun.
Amischiefr
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.