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

450

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

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

Я хочу, чтобы div 'view' расширялся до всей ширины, доступной после того, как div дерева заполнил необходимое пространство. В настоящее время мой div 'view' изменен для контента, содержащего его Также хорошо, если оба divs занимают целую высоту

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

Развернуть div до максимальной ширины, когда float: left установлен потому что левая имеет фиксированную ширину.

Справка с div-make div соответствует оставшейся ширине потому что мне нужны два столбца, выровненные влево

  • 1
    связанный stackoverflow.com/a/22719552/759452
  • 1
    Либо я не понимаю вопрос, либо я не понимаю, как вы выбираете принятый ответ, потому что там и ширина, и высота зафиксированы с неудобством overflow hidden
Теги:
multiple-columns

19 ответов

904
Лучший ответ

Решение этого на самом деле очень просто, но не совсем очевидно. Вы должны вызвать что-то, называемое "контекстом форматирования блоков" (BFC), который определенным образом взаимодействует с поплавками.

Просто возьмите этот второй div, удалите float и принесите его overflow:hidden. Любое значение переполнения, отличное от видимого, делает блок, который он устанавливает, становится BFC. BFC не позволяют потокам-потомкам избегать их, а также не позволяют им перемещаться в них. Чистый эффект здесь заключается в том, что плавающий div будет делать это, тогда второй div будет обычным блоком, занимающим всю доступную ширину, за исключением того, что занято поплавком.

Это должно работать во всех существующих браузерах, хотя вам, возможно, придется запускать hasLayout в IE6 и 7. Я не могу вспомнить.

Demos:

  • 0
    Похоже, что он работает в режиме совместимости IE 7 с IE 7 без hasLayout, поэтому я предполагаю, что IE 7 не требует hasLayout.
  • 26
    Отличный ответ! Но вы ошибаетесь, когда говорите, что «любое значение переполнения, отличное от auto», сделает его BFC. Вы имеете в виду, что любое значение переполнения, отличное от значения по умолчанию (видимого), сделает его BFC. На самом деле, переполнение авто тоже отлично работает - это то, что я бы порекомендовал (на тот случай, если у вас есть относительно позиционированные элементы, которые могут выглядывать из этого div).
Показать ещё 23 комментария
39

Я только что открыл магию гибких ящиков (display: flex). Попробуйте следующее:

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

Ящики с флешками дают мне контроль, который я пожелал css в течение 15 лет. Наконец-то здесь! Дополнительная информация: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

  • 0
    Я не знаю, что вы обнаружили, но ваш код не работает в последнем Chrome jsfiddle.net/fjb548kw/3
  • 0
    @YevgeniyAfanasyev Я удалил "поплавок: слева"; чтобы исправить проблему. Спасибо за примечание!
Показать ещё 2 комментария
24

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

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

Если один из столбцов был фиксированной шириной, это было бы немного сложнее, но вполне выполнимо.

В обоих столбцах переменной ширины IMHO вам нужно просто использовать таблицу с двумя столбцами.

  • 11
    Таблица не будет очень хорошей в адаптивном дизайне, где вы хотите, чтобы правая колонка скользила под левой на маленьких устройствах.
  • 1
    Есть несколько приемов адаптивного дизайна для работы с таблицами: css-tricks.com/responsive-data-tables
Показать ещё 1 комментарий
18

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

.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, где каждый может иметь переменную ширину». В своем ответе вы должны знать ширину первого столбца, чтобы она не была переменной. Вы могли бы также установить фиксированную ширину в обоих столбцах и просто плавать их.
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>
  • 0
    +1, потому что ваш пример, кажется, работает, но в моем реальном сценарии некоторые из того, как содержимое «view» заползает в div «tree», так как div дерева не равен 100%, может быть каким-то javascript заставляет его быть маленьким и после высоты дерева Я вижу содержимое просмотра
  • 0
    В этом случае, если вы знаете максимальную ширину левого столбца, вы можете либо присвоить ему стиль max-width (не работает в IE), либо подумать о margin-left (остерегайтесь ошибки двойного поля в IE) или обивка налево.
Показать ещё 1 комментарий
8

Используйте calc. example`

.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 работают нормально) или как процент чего-то, что хорошо отделяет его.

`

  • 0
    лучшее решение, когда ширина первого столбца фиксирована. +1
5

Flexbox решение

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

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

5

Я не понимаю, почему люди готовы так усердно работать, чтобы найти решение с чистым CSS для простых макетов столбцов, которые SO EASY используют старый тег 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, почему бы и нет, по крайней мере, любопытство, если это возможно?
  • 1
    Это потому, что если вы хотите разместить media-queries для размещения обоих столбцов друг над другом на небольших устройствах, это невозможно с помощью старого тега table . Чтобы это работало, вам нужно применить стили таблиц CSS . Итак, в настоящее время лучше решить эту проблему с помощью CSS если вы хотите адаптивный макет для любого размера экрана.
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>
  • 0
    Я хочу что-то вроде строки состояния с фиксированными элементами слева, фиксированными элементами справа и одной строкой сообщения, которая использует все оставшееся пространство. Я начал с этого ответа и добавил свое сообщение div ПОСЛЕ плавания с: height: 20px; пустое пространство: nowrap; переполнение: скрытое; текст переполнение: клип
1

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

dl {
  display: grid;
  grid-auto-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>
1

Несколько другая реализация,

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

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

1

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

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>

<head>
  <style type="text/css">
    .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%;
    }
    .txtCont .ip {
      width: 100%;
      max-width: 100%;
      min-width: 30%
    }
  </style>
</head>

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

</html>
  • 2
    Нет ссылки на HTML для класса CSS .ip, и он не работает в IE7
1

Спасибо за пробную версию 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

Как использовать функцию calc, если вы используете последние браузеры (IE >= 9, FF >= 19, chrome >= 26, safari >= 6), а ширина другого раздела в той же строке фиксирована?

width: calc(100% - 20px)

Вместо 20px вы можете записать фиксированную ширину другого раздела в той же строке. Таким образом, ширина будет вычисляться и применяться, т.е. Оставшаяся ширина.

P.S. Нет поддержки Opera!: (

0

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

  • 2
    Потому что это поместит второй поплавок ниже первого, потому что он слишком широкий.
-1

Я написал функцию 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"));
            }
        });
    });
}
-2

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

<!DOCTYPE html>
 <html>
   <link rel="stylesheet" href="/w3.css">
   <body>
    <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>
   </body>
 </html>

не забудьте связать css-библиотеку W3 в заголовке html-страницы:

<link rel="stylesheet" href="/w3.css">

https://www.w3schools.com/w3css/tryit.asp?filename=tryw3css_grid_rest&stacked=h

-2

Посмотрите на доступные рамки компоновки CSS. Я бы рекомендовал Simpl или немного более сложную структуру Blueprint.

Если вы используете Simpl (который включает в себя импорт только одного файла simpl.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 единиц.

Это просто.

  • 0
    будут ли оба столбца переменной ширины?
-4

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню