Rozwiń div, aby wypełnić pozostałą szerokość


552

Chcę mieć dwukolumnowy układ div, w którym każdy może mieć zmienną szerokość, np

div {
  float: left;
}

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

Chcę, aby div „view” rozszerzył się na całą szerokość dostępną po tym, jak div „tree” wypełnił potrzebną przestrzeń.

Obecnie mój div „view” jest przeskalowany do zawartości, która zawiera. Dobrze będzie, jeśli oba div zajmą całą wysokość.


Nie powielane zastrzeżenie:



1
Albo nie rozumiem pytania, albo nie rozumiem, w jaki sposób wybierasz akceptowaną odpowiedź, ponieważ tam zarówno szerokości, jak i wysokości są ustalone z niedogodnościąoverflow hidden
użytkownik10089632

Odpowiedzi:


1013

Rozwiązaniem tego problemu jest rzeczywiście bardzo proste, ale nie na wszystko oczywiste. Musisz uruchomić coś, co nazywa się „kontekstem formatowania bloku” (BFC), który współdziała z elementami zmiennoprzecinkowymi w określony sposób.

Po prostu weź ten drugi div, usuń pływak i daj go overflow:hiddenzamiast tego. Każda wartość przepełnienia inna niż widoczna powoduje, że ustawiony blok staje się BFC. BFC nie pozwalają pływakom potomnym na ucieczkę od nich, ani nie pozwalają intruzom rodzeństwa / przodkom na ingerencję w nie. Efektem netto jest to, że pływający div będzie robił swoje, wtedy drugi div będzie zwykłym blokiem, zajmującym całą dostępną szerokość oprócz tej zajmowanej przez float .

Powinno to działać we wszystkich obecnych przeglądarkach, chociaż może być konieczne wyzwolenie hasLayout w IE6 i 7. Nie pamiętam.

Dema:


28
Doskonała odpowiedź! Ale mylisz się, gdy mówisz, że „każda wartość przepełnienia inna niż auto” spowoduje, że będzie to BFC. Masz na myśli, że każda wartość przepełnienia inna niż domyślna (widoczna) spowoduje, że będzie to BFC. W rzeczywistości automatyczne przelewanie również działa idealnie - to właśnie poleciłbym (na wypadek, gdybyś miał względnie ustawione elementy, które mogłyby zerkać z tego diva).
BT

52
Ten artykuł ma ładne wyjaśnienie: colinaarts.com/articles/the-magic-of-overflow-hidden
Max Cantor

1
Co jeśli zawartość jest wystarczająco duża, aby przepełnić div?
giannis christofakis

11
Należy zauważyć, że kolejność dzieci ma znaczenie. Element pływający o stałej szerokości musi znajdować się nad drugim. Zajęło mi to zbyt długo, aby zrozumieć, dlaczego nie działało to dla mnie przy przełączonym zamówieniu.
Riplexus,

2
Napisałem odpowiedź wyjaśniającą, dlaczego niewidoczny przepełnienie wszystkich elementów wyzwala BFC, na podstawie odpowiedzi udzielonych przez Davida i Borysa, które można znaleźć tutaj: stackoverflow.com/questions/9943503/... Czy moja interpretacja była poprawna?
BoltClock

104

Właśnie odkryłem magię elastycznych pudełek (display: flex). Spróbuj tego:

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

Pudełka Flex dają mi kontrolę, jakiej życzyłem sobie css od 15 lat. W końcu jest tutaj! Więcej informacji: https://css-tricks.com/snippets/css/a-guide-to-flexbox/


Nie wiem, co odkryłeś
Jewgienij

@YevgeniyAfanasyev Usunąłem „float: left;” naprawić problem. Dzięki za notatkę!
BT

Dziękuję Ci. Czy możesz wyjaśnić, dlaczego tak jestflex-grow: 100; zamiast flex-grow: 1;?
Jewgienij Afanasyjew

2
@YevgeniyAfanasyev Bez konkretnego powodu, z wyjątkiem tego, jak lubię to robić. To pozwala mi myśleć procentowo, więc gdybym mógł zrobić coś takiego jak ustawić #a na, flex-grow:10a następnie ustawiłbym #b na flex-grow: 90tak, aby #a wynosiłaby 10% szerokości linii, a #b byłby 90% szerokości linii. Jeśli żaden inny element nie ma stylu elastycznej szerokości, to nie ma znaczenia technicznego.
BT

działało to dla mnie najlepiej, próbując umieścić wejście i przycisk obok siebie, jakby były jednym.
Souleste

28

Rozwiązanie Flexbox

Po to jest ta flex-growwłaściwość.

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>

Uwaga: Dodaj prefiksy dostawcy elastycznego, jeśli jest to wymagane obsługiwane przeglądarki .


27

Byłby to dobry przykład czegoś, co jest trywialne w stosunku do tabel i trudne (jeśli nie niemożliwe, przynajmniej w sensie różnych przeglądarek) do CSS.

Gdyby obie kolumny miały stałą szerokość, byłoby to łatwe.

Gdyby jedna z kolumn miała stałą szerokość, byłoby to nieco trudniejsze, ale całkowicie wykonalne.

Przy zmiennej szerokości obu kolumn IMHO wystarczy użyć tabeli dwukolumnowej.


11
Stół nie będzie zbyt dobry w responsywnym projekcie, w którym chcesz, aby prawa kolumna przesuwała się pod lewą stroną na małych urządzeniach.
S ..

1
Istnieje kilka elastycznych sztuczek projektowych do pracy z tabelami: css-tricks.com/responsive-data-tables
Rikki

Często mam teraz tendencję do projektowania całkowicie dwóch oddzielnych układów i zmiany na telefonie komórkowym za pomocą zapytań o media. display:none;Mimo że w miarę możliwości reaguję w 100% na ruchomej skali, czasem lepiej jest całkowicie zmienić projekt na urządzenie mobilne wykorzystujące dotyk ekranu dotykowego i styl przycisku.
Bysander

22

Sprawdź to rozwiązanie

.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
Jest to ogólnie lepsze rozwiązanie, ponieważ ukrywanie przelewu nie zawsze jest pożądane.
Joseph Lennox,

3
Dla OP: „Chcę mieć dwukolumnowy układ div, w którym każdy może mieć zmienną szerokość”. W swojej odpowiedzi musisz znać szerokość pierwszej kolumny, więc nie jest ona zmienna. Równie dobrze możesz ustawić stałe szerokości dla obu kolumn i po prostu je unieść.
Jacob Alvarez

17

Użyj 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>

Problem polega na tym, że wszystkie szerokości muszą być wyraźnie zdefiniowane, albo jako wartość (px i em działają dobrze), albo jako procent czegoś wyraźnie zdefiniowanego.


15

Tutaj może to pomóc ...

<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, ponieważ twój przykład wydaje się działać, ale w moim prawdziwym scenariuszu, w jaki sposób zawartość z „widoku” wkrada się w div drzewa Widzę przeglądać zawartość
Anurag Uniyal

W takim przypadku, jeśli znasz maksymalną szerokość lewej kolumny, możesz nadać jej styl maksymalnej szerokości (nie działa w IE) lub pomyśleć o marginesie w lewo (uważaj na błąd podwójnego marginesu w IE) lub padding-left.
a6hi5h3k

To było świetne! Używam go jako rozwiązania jednorazowego:<div class="clear" style="clear: both; height: 1px; overflow: hidden; font-size:0pt; margin-top: -1px;"></div>
ajwest

5

Nie rozumiem, dlaczego ludzie tak ciężko pracują, aby znaleźć rozwiązanie czysto CSS dla prostych układów kolumnowych, które są TAK ŁATWE przy użyciu starego TABLE znacznika.

Wszystkie przeglądarki nadal mają logikę układu tabeli ... Może nazywaj mnie dinozaurem, ale mówię, że ci to pomoże.

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

O wiele mniej ryzykowne również pod względem zgodności z różnymi przeglądarkami.


2
tak, ale jeśli wszystko jest wykonywane przez css, dlaczego nie to, przynajmniej ciekawość, jeśli jest to możliwe?
Anurag Uniyal

2
Jest tak, ponieważ jeśli chcesz media-queriesumieścić obie kolumny jedna nad drugą na małych urządzeniach, to jest niemożliwe ze starym tableznacznikiem. Aby to działało, musisz zastosować CSSstyle tabel. Tak więc na dzień dzisiejszy lepiej to rozwiązać, CSSjeśli chcesz responsywny układ dla dowolnego rozmiaru ekranu.
ElChiniNet

5

Jeśli szerokość drugiej kolumny jest stała, skorzystaj z calc funkcji CSS działającej we wszystkich popularnych przeglądarkach :

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

W ten sposób szerokość drugiego rzędu zostanie obliczona (tj. Pozostała szerokość) i zastosowana odpowiednio.


Jest to najlepsza odpowiedź, o ile używa się czegoś innego niż Flexbox, na przykład css-grid. Działa również z tym, position: fixedco czyni go idealnym wyborem! Dziękuję Ci!
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>


Chcę coś w rodzaju paska stanu ze stałymi elementami po lewej stronie, stałymi elementami po prawej stronie i jednym wierszem wiadomości, który wykorzystuje całe pozostałe miejsce. Zacząłem od tej odpowiedzi i dodałem wiadomość div PO pływakach z: height: 20px; biała przestrzeń: nowrap; przelew: ukryty; przepełnienie tekstu: klip
englebart

3

Możesz wypróbować układ siatki CSS .

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 - określa zdolność do wzrostu elementu flex w razie potrzeby. Akceptuje wartość jednostkową, która służy jako proporcja. To określa, jaka ilość dostępnego miejsca w elastycznym pojemniku powinien zająć przedmiot.

Jeśli wszystkie elementy mają Flex-Grow ustawioną na 1, pozostała przestrzeń w pojemniku zostanie równo rozdzielona na wszystkie dzieci. Jeśli jedno z dzieci ma wartość 2, pozostałe miejsce zajmie dwa razy więcej miejsca niż inne (lub przynajmniej spróbuje to zrobić). Zobacz więcej tutaj

.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

Pat - masz rację. Dlatego to rozwiązanie zadowoli zarówno „dinozaury”, jak i współczesnych. :)

.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
Nie ma odwołania HTML dla klasy css .ip i nie działa w IE7
Keith K

1

Możesz użyć biblioteki CSS W3, która zawiera klasę o nazwie, restktóra robi tylko to:

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

Nie zapomnij połączyć biblioteki CSS na stronie header:

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

Oto oficjalne demo: W3 School Tryit Editor


Wygląda na to, że dodaje tylko „przepełnienie: ukryte”, co czyni go gorszą wersją już udzielonej odpowiedzi
vpzomtrrfrt

0

Nie jestem pewien, czy jest to odpowiedź, której oczekujesz, ale dlaczego nie ustawisz szerokości drzewa na „auto” i szerokości „widoku” na 100%?


3
Ponieważ spowoduje to umieszczenie drugiego elementu pływającego poniżej pierwszego, ponieważ jest zbyt szeroki.
cletus,

0

Zobacz dostępne struktury układu CSS. Polecam Simpl Lub nieco bardziej skomplikowane, ramy Blueprint.

Jeśli używasz Simpl (co wymaga importu tylko jednego pliku simpl.css ), możesz to zrobić:

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

, dla układu 50–50 lub:

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

, dla 25-75.

To takie proste.


czy obie kolumny będą miały zmienną szerokość?
Anurag Uniyal

0

Dzięki za wtyczkę Simpl.css!

pamiętaj, aby tak zawinąć wszystkie kolumny ColumnWrapper.

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

Mam zamiar wydać wersję 1.0 Simpl.css, więc pomóżcie rozpowszechniać!


0

Napisałem funkcję javascript, którą wywołuję z jQuery $ (document) .ready (). Spowoduje to przeanalizowanie wszystkich dzieci div rodzica i zaktualizuje tylko najbardziej odpowiednie dziecko.

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

Jest to dość łatwe w użyciu Flexboksa. Zobacz fragment poniżej. Dodałem pojemnik owijający, aby kontrolować przepływ i ustawić wysokość globalną. Dodano również granice w celu identyfikacji elementów. Zauważ, że div div również teraz rozwija się do pełnej wysokości, zgodnie z wymaganiami. W scenariuszu rzeczywistym należy używać prefiksów dostawców dla Flexbox, ponieważ nie jest jeszcze w pełni obsługiwany.

Opracowałem bezpłatne narzędzie do rozumienia i projektowania układów za pomocą Flexboksa. Sprawdź to tutaj: 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>


czy przeczytałeś WSZYSTKIE poprzednie odpowiedzi przed dodaniem swoich? wydaje się, że nie ...
Temani Afif,

na marginesie, nie trzeba dodawać, stretchponieważ jest to wartość domyślna i nie trzeba display:flex
ustawiać

Zastanawiam się, dlaczego głosowanie bez komentarza. Czy ta odpowiedź nie odpowiada na pytanie? Dlaczego? Jeśli próba pomocy innym zostanie ukarana, zastanowię się dwa razy przed moją kolejną odpowiedzią,
Mario Vázquez,

1
masz dwa komentarze po przegłosowaniu, to nie wystarczy?
Temani Afif,

Temari, sprawdziłeś moje narzędzie? Czy nie uważasz, że jest przydatny i mógłby pomóc innym? Czy uważasz, że nie ma to związku z pytaniem? Gdzie jest twoja odpowiedź na to pytanie? Nie widzę tego Jaka jest twoja rola tutaj?
Mario Vázquez,

-3

Jeśli obie szerokości mają zmienną długość, dlaczego nie obliczyć szerokości za pomocą skryptów lub serwera?

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

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

3
Skąd serwer wie, jak będzie działał silnik układu klienta?
Kev

Proste: opracuj dla 90% dostępnych przeglądarek :) IE 7+, FF3 + i Safari obsługują CSS 3. Możesz również dołączyć standardowy element IE6 <! - [if lte IE 6]>. Nawiasem mówiąc, która przeglądarka nie obsługuje stylu = "width:%" ??
amischiefr

Nie wiem, jak można to zrobić po stronie serwera, ale tak, może to zrobić skrypt JavaScript, ale chcę tego uniknąć, chyba że css / html nie może tego zrobić
Anurag Uniyal

Które nie może. Dlatego jeśli chcesz, aby oba były dynamiczne, musisz to zrobić po stronie skryptu lub serwera.
amischiefr
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.