Разверните div, чтобы заполнить оставшуюся ширину


552

Я хочу макет div с двумя столбцами, где каждый может иметь переменную ширину, например

div {
  float: left;
}

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

I want the 'view' div to expand to the whole width available after 'tree' div has filled needed space.

Currently, my 'view' div is resized to content it contains It will also be good if both divs take up the whole height.


Не дублировать отказ от ответственности:



1
Либо я не понимаю вопрос, либо я не понимаю, как вы выбираете принятый ответ, потому что там и ширина, и высота зафиксированы с неудобствамиoverflow hidden
user10089632

Ответы:


1012

The solution to this is actually very easy, but not at all obvious. You have to trigger something called a "block formatting context" (BFC), which interacts with floats in a specific way.

Just take that second div, remove the float, and give it overflow:hidden instead. Any overflow value other than visible makes the block it's set on become a BFC. BFCs don't allow descendant floats to escape them, nor do they allow sibling/ancestor floats to intrude into them. The net effect here is that the floated div will do its thing, then the second div will be an ordinary block, taking up all available width except that occupied by the float.

This should work across all current browsers, though you may have to trigger hasLayout in IE6 and 7. I can't recall.

Demos:


28
Excellent answer! But you're wrong when you say "any overflow value other than auto" will make it a BFC. What you mean is any overflow value other than the default (visible) will make it a BFC. In fact, overflow auto works perfectly too - thats what I'd recommend (just in case you do have relatively positioned elements that might peek out of that div).
B T

52
This article has a nice explanation: colinaarts.com/articles/the-magic-of-overflow-hidden
Max Cantor

1
What if the content is big enough to overflow the div ?
giannis christofakis

11
It is important to note, that the order of the children matters. The floating element with fixed width has to be above the other one. Took me too long to figure out, why it didn't worked for me with switched order.
Riplexus

2
I wrote an answer explaining why a non-visible overflow of all things triggers a BFC, based on responses given by David and Boris, which can be found here: stackoverflow.com/questions/9943503/… Was my interpretation correct?
BoltClock

106

I just discovered the magic of flex boxes (display: flex). Try this:

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

Flex boxes give me the control I've wished css had for 15 years. Its finally here! More info: https://css-tricks.com/snippets/css/a-guide-to-flexbox/


I don't know what you discovered, but your code is not working in latest Chrome jsfiddle.net/fjb548kw/3
Yevgeniy Afanasyev

@YevgeniyAfanasyev I removed the "float:left;" to fix the issue. Thanks for the note!
B T

Спасибо. Можете ли вы объяснить, почему у вас flex-grow: 100;вместо flex-grow: 1;?
Евгений Афанасьев

2
@YevgeniyAfanasyev Нет особой причины, кроме того, что мне нравится это делать. Это позволяет мне думать в процентах, поэтому, если бы я мог сделать что-то вроде установки #a в, flex-grow:10а затем я бы установил #b в значение, flex-grow: 90чтобы #a было бы 10% ширины линии, а #b было бы 90% ширины линии. Если никакие другие элементы не имеют стиля гибкой ширины, то это не имеет значения с технической точки зрения.
BT

это работало лучше всего для меня, пытаясь разместить вход и кнопку рядом, как если бы они были одним.
Souleste

29

Решение Flexbox

Это то, что flex-growсвойство для.

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>

Примечание. Добавьте префиксы поставщиков Flex, если это требуется поддерживаемыми браузерами .


27

Это было бы хорошим примером того, что тривиально сделать с таблицами и трудно (если не невозможно, по крайней мере в смысле кроссбраузерности) делать с CSS.

Если бы оба столбца имели фиксированную ширину, это было бы легко.

If one of the columns was fixed width, this would be slightly harder but entirely doable.

With both columns variable width, IMHO you need to just use a two-column table.


11
Таблица не будет очень хорошей в адаптивном дизайне, где вы хотите, чтобы правая колонка скользила под левой на маленьких устройствах.
S ..

1
Есть несколько приемов адаптивного
Rikki

Сейчас я часто полностью разрабатываю два отдельных макета и меняю их на мобильном телефоне с помощью медиазапросов. display:none;При этом максимально адаптируясь к 100% на скользящей шкале, иногда лучше полностью изменить дизайн для мобильного устройства, используя сенсорный экран и стиль кнопки.
Бисандр

22

Проверьте это решение

.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
Как правило, это лучшее решение, потому что скрытие переполнения не всегда желательно.
Джозеф Леннокс

3
Для OP: «Я хочу двухстолбцовый макет div, где каждый может иметь переменную ширину». В своем ответе вы должны знать ширину первого столбца, чтобы она не была переменной. Вы можете также установить фиксированную ширину в обоих столбцах и просто плавать их.
Джейкоб Альварес

17

Используйте 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>

Проблема в том, что все ширины должны быть явно определены, либо как значение (px и em работают нормально), либо как процент от чего-то явно определенного самого себя.


15

Здесь это может помочь ...

<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, потому что ваш пример, кажется, работает, но в моем реальном сценарии некоторые из того, как содержимое «view» заползает в div «tree», так как div дерева не равен 100%, может быть некоторым javascript заставляет его быть маленьким и после высоты дерева Я вижу содержание просмотра
Anurag Uniyal

В этом случае, если вы знаете максимальную ширину левого столбца, вы можете либо присвоить ему стиль max-width (не работает в IE), либо подумать о margin-left (остерегайтесь ошибки двойного поля в IE) или обивка налево.
a6hi5h3k

Это было прекрасно! Я использую его как одноразовое решение:<div class="clear" style="clear: both; height: 1px; overflow: hidden; font-size:0pt; margin-top: -1px;"></div>
ajwest

5

Я не понимаю, почему люди хотят так усердно работать, чтобы найти решение с чистым CSS для простых столбчатых макетов, которые НАСТОЛЬКО ЛЕГКО используют старый TABLEтег.

Все браузеры все еще имеют логику раскладки таблиц ... Возможно, вы называете меня динозавром, но я говорю, пусть это поможет вам.

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

Гораздо менее рискованно с точки зрения кросс-браузерной совместимости.


2
да, но если все делает css, почему бы и нет, по крайней мере, любопытство, если это возможно?
Anurag Uniyal

2
Это потому, что если вы хотите поместить media-queriesоба столбца один над другим на небольших устройствах, это невозможно сделать со старым tableтегом. Чтобы это работало, вам нужно применить CSSстили таблиц. Итак, на данный момент лучше решить эту проблему, CSSесли вы хотите адаптивный макет для любого размера экрана.
ElChiniNet

5

Если ширина другого столбца фиксирована, как насчет использования calcфункции CSS, работающей для всех распространенных браузеров :

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

Таким образом, ширина второго ряда будет рассчитана (т. Е. Оставшаяся ширина) и применена соответственно.


Это лучший ответ, насколько использовать что - нибудь другое , чем Flexbox, как, например, css-grid. Также работает, position: fixedчто делает все вокруг идеальным выбором! Спасибо!
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>


Я хочу что-то вроде строки состояния с фиксированными элементами слева, фиксированными элементами справа и одной строкой сообщения, которая использует все оставшееся пространство. Я начал с этого ответа и добавил свое сообщение div ПОСЛЕ плавания с: height: 20px; пустое пространство: nowrap; переполнение: скрытое; переполнение текста: клип
englebart

3

Вы можете попробовать CSS Grid Layout .

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 - определяет способность элемента flex расти в случае необходимости. Он принимает значение без единицы, которое служит пропорцией. Он определяет, какое количество доступного пространства внутри гибкого контейнера должно занимать элемент.

Если для всех элементов flex-grow установлено значение 1, оставшееся пространство в контейнере будет распределено в равной степени всем дочерним элементам. Если один из дочерних элементов имеет значение 2, оставшееся пространство займет в два раза больше места, чем остальные (или попытается, по крайней мере). Подробнее здесь

.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

Немного другая реализация,

Две панели div (content + extra), расположенные рядом, content panelрасширяются, если их extra panelнет.

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


1

Пэт - Вы правы. Вот почему это решение удовлетворит и «динозавров», и современников. :)

.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
Нет ссылки на html для класса css .ip, и он не работает в IE7
Кейт К

1

Вы можете использовать библиотеку CSS W3, которая содержит класс, restкоторый делает это:

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

Не забудьте связать библиотеку CSS на странице header:

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

Вот официальная демоверсия: W3 School Tryit Editor


Похоже, это просто добавляет «переполнение: скрытый», что делает его худшим вариантом ответа, который уже дан
vpzomtrrfrt

0

Я не уверен, что это ответ, который вы ожидаете, но почему бы вам не установить ширину дерева на «auto» и ширину «View» на 100%?


3
Потому что это поместит второй поплавок ниже первого, потому что он слишком широкий.
Клет

0

Посмотрите доступные CSS-макеты. Я бы порекомендовал Simpl или, чуть более сложный, Blueprint framework.

Если вы используете Simpl (который включает в себя импорт только одного файла simp.css ), вы можете сделать это:

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

, для макета 50-50, или:

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

для 25-75.

Это так просто.


оба столбца будут переменной ширины?
Anurag Uniyal

0

Спасибо за плагин Simpl.css!

не забудьте обернуть все ваши столбцы ColumnWrapperтак.

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

Я собираюсь выпустить версию 1.0 Simpl.css, так что помогите распространить информацию!


0

Я написал функцию javascript, которую я вызываю из jQuery $ (document) .ready (). Это проанализирует все дочерние элементы родительского элемента div и обновит только самого правого дочернего элемента.

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

Это довольно легко, используя flexbox. Смотрите фрагмент ниже. Я добавил контейнер-обертку для управления потоком и установил глобальную высоту. Границы были добавлены, чтобы идентифицировать элементы. Обратите внимание, что div теперь расширяется до полной высоты, как требуется. Префиксы поставщика следует использовать для flexbox в реальном сценарии, поскольку он еще не полностью поддерживается.

Я разработал бесплатный инструмент для понимания и разработки макетов с помощью flexbox. Проверьте это здесь: 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>


Вы прочитали ВСЕ предыдущие ответы, прежде чем добавить свой? кажется нет ...
Темани Афиф

в качестве примечания, вам не нужно добавлять, stretchпотому что это значение по умолчанию, и нет необходимости делать из дочернего элемента гибкий контейнер, поэтому display:flexон бесполезен для внутренних элементов
Temani Afif

Интересно, почему понизили, без всяких комментариев. Разве этот ответ не отвечает на вопрос? Почему? Если попытка помочь другим будет оштрафована, я подумаю дважды перед следующим ответом,
Марио Васкес

1
Вы получили два комментария после downvote, это не достаточно?
Темани Афиф

Темари, ты проверил мой инструмент? Тебе не кажется полезным и может помочь другим? Как вы думаете, это не связано с вопросом? Где ваш ответ на этот вопрос? Я не вижу этого Какова твоя роль здесь?
Марио Васкес

-3

Если обе ширины имеют переменную длину, почему бы вам не рассчитать ширину с некоторыми сценариями или на стороне сервера?

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

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

3
Как сервер узнает, как будет работать механизм компоновки клиента?
Кев

Просто: разработайте его для 90% браузеров :) IE 7+, FF3 + и Safari поддерживают CSS 3. Вы также можете включить стандартный элемент IE6 <! - [if lte IE 6]>. Кстати, какой браузер не поддерживает style = "width:%" ??
amischiefr

Я не знаю, как это можно сделать на стороне сервера, но да, некоторые javscript могут это делать, но я хочу избежать этого, если css / html не может это сделать
Anurag Uniyal

Который не может. Поэтому, если вы хотите, чтобы оба были динамическими, вы должны сделать это либо на стороне сценария, либо на стороне сервера.
amischiefr
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.