Разделить доступную ширину между двумя divs

У меня есть контейнер (ширина неизвестна), содержащая четыре divs, следующим образом:

| Div1 | Div2 ............... | .............. Div3 | Div4 |

Самые левые и правые div (Div1/Div4) - фиксированная ширина; что легкая часть.

Ширина Div2/Div3 неизвестна, и я хотел бы избежать установки фиксированной ширины для них, так как в зависимости от содержимого можно быть намного шире, чем другой (поэтому я не могу просто использовать, например, каждый из них 50 % доступного пространства)

Я хотел бы, чтобы ширина Div2/Div3 автоматически вычислялась браузером, а затем, если осталось оставшееся пространство, они должны растягиваться, чтобы заполнить любое оставшееся пространство (неважно, как разделить оставшееся пространство между Div2/div3)

Теперь я приближаюсь к этому:

  • Div1 перемещается влево (или абсолютно позиционируется)
  • Div4 плавает вправо (или абсолютно позиционируется)
  • Div2 имеет левый край, равный ширине Div1 (известный)
  • Div3 имеет margin-right, равный ширине Div4 (известный)

Мой вопрос в том, как растянуть Div2 и Div3, чтобы заполнить оставшуюся доступную ширину? Я предполагаю, что одним из вариантов было бы использовать display: table, а другая возможность была бы flex-box. Есть ли альтернативы?

Обновление: Отредактировано для ясности.

Обновление 2: Обратите внимание: я не могу предположить, что Div2 и Div3 должны получить 50% доступного пространства. Это прямо указано в вопросе, но почему-то я получаю ответы на основе этого предположения.

Ответы

Ответ 1

Использовать overflow:hidden (или переполнение: автоматически - до тех пор, пока переполнение не будет видимым [по умолчанию]), чтобы запустить block formatting contexts, чтобы заполнить оставшуюся ширину

(я предположил фиксированную ширину 100px для div1 и div4)

FIDDLE

Разметка

<div class="div1">DIV 1</div>
<div class="container">
    <div class="div2">DIV 2</div>
    <div class="div3">DIV 3</div>
</div>
<div class="div4">DIV 4</div>

CSS

html,body,div
{
    height: 100%;
}
.div1 {
    float:left;
    width: 100px;
    background: aqua;
}
.container
{
   overflow: hidden;
   padding-right: 100px;
   box-sizing: border-box;
    background: green;
}
.div2 {
    background:yellow;
    float:left;
}
.div3 {
    background:brown;
    overflow: hidden;
}
.div4 {
    position: absolute;
    right:0;
    top:0;
    background:pink;
    width: 100px; 
}

Ответ 2

Я придумал 3 разных решения, чтобы получить правильную ширину:

  • Ячейки таблицы:

    parent: {display: table}
    
    childs: {display: table-cell}
    
  • Сетка Flex:

    parent: {display: inline-flex}
    
    childs: {flex-grow: 1}
    
  • Коробка для определения размера коробки:

    parent: {float: left}
    
    container: {box-sizing: border-box; padding: 0 WIDTH}
    
    childs: {width: 50%}
    

Последнее решение использует дополнительную html-разметку и выравнивает элементы по вертикали, используя относительное позиционирование (означает, что вы должны иметь фиксированную высоту).

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

Демо: http://jsfiddle.net/R8mqR/9/embedded/result/

Ответ 3

Здесь решение с использованием display: table без фактического использования таблицы, tr, td и т.д.: (FIDDLE)

HTML

<div id="foo">
    <div id="left"></div>
    <div id="center1">asdfasdfasdf</div>
    <div id="center2"> asdfasdlfkjasl;dkfjalsdjkf</div>
    <div id="right"></div>
</div>

CSS

div {
    border: solid 1px black ;
    height: 20px;
}

#foo {
    border: none; 
    display: table; 
    width: 100%;
}

#left, #right {width: 100px;}

#foo > div {
    display: table-cell;
}

Ответ 4

Вы можете обернуть Div2 и Div3 внутри родительского Div и установить ширину Div2 и Div3 на 50%.

<div id="div1"> </div>
<div style="margin-left:*div1width*;margin-right:*div4width*;">
  <div id="div2" style="width:50%"> </div>
  <div id="div3" style="width:50%"> </div>
</div>
<div id="div4"> </div>

Ответ 5

Вычисление (http://caniuse.com/#search=calc) способ:

#foo {
    position: relative;
    background-color: #ccc;
}

#foo:after {
    content: "";
    clear: both;
}

#foo > div {
    width: calc(50% - 100px);
    height: 100px;
    float: left;
}

#foo > div:nth-child(1) {
    width: 100px;
    background-color: #f00;
}

#foo > div:nth-child(2) {
    background-color: #0f0;
}

#foo > div:nth-child(3) {
    background-color: #00f;
}

#foo > div:nth-child(4) {
    width: 100px;
    background-color: #000;
}

http://jsfiddle.net/coma/YPWcW/

Прокладка/позиция:

#foo {
    padding: 0 100px;
    position: relative;
    background-color: #ccc;
}

#foo:after {
    content: "";
    clear: both;
}

#foo > div {
    width: 50%;
    height: 100px;
    float: left;
}

#foo > div:nth-child(1) {
    width: 100px;
    background-color: #f00;
    float: none;
    position: absolute;
    top: 0;
    left: 0;
}

#foo > div:nth-child(2) {
    background-color: #0f0;
}

#foo > div:nth-child(3) {
    background-color: #00f;
}

#foo > div:nth-child(4) {
    width: 100px;
    background-color: #000;
    float: none;
    position: absolute;
    top: 0;
    right: 0;
}

http://jsfiddle.net/coma/qqR4Z/

Вы можете использовать min-width:

http://jsfiddle.net/coma/38KQt/2/

Ответ 6

Я думаю, что можно использовать модель flex box в css3

Следующий код работает в IE10, chrome, firefox, safari

<div class="mainbox">
<div class="marpad marpadout">
       div1
    </div>
    <div class="subbox marpad">
       div2
    </div>
    <div class="subbox marpad">
       div3
    </div>
    <div class="marpad marpadout">
       div4
    </div>
</div>

Стили:

.mainbox{
    width:100%;
    display:-moz-box;
    display:-webkit-box;
    display:-ms-flexbox;
    display:box;
    background:#ff0000;
 }

.subbox{
    -moz-box-flex:1;
    -webkit-box-flex:1;
    -ms-flex:1; 
    box-flex:1;
}

.marpad{
margin:5px;
padding: 0 10px 10px 0;
background:#ccc;
}
.marpadout{
width:100px;
}

Ответ 7

Мое решение заимствует другие, которые уже были отправлены, но, протестировав их, я обнаружил, что содержимое в двух центральных divs испортилось с распределением ширины... Они сохраняли бы такую ​​же ширину, пока они точно то же содержимое, но будет неравномерно, как только получится больше контента.

Итак, в моем решении я использовал jQuery для распределения ширины остатка в двух центральных divs, , делая их ширину даже независимо от различий в их содержании.

Bonus #1: jQuery не обязательно должен знать ширину левой и правой divs явно, поскольку он выбирает любую ширину, определенную с помощью CSS.

Bonus #2: Легко указать, сколько центральных разделов есть и распределить оставшуюся ширину одинаково среди всех из них. Просто измените число, на которое делится оставшаяся ширина.

Вот скрипка. Ниже приведено решение, опубликованное в скрипке, упрощенное. Скрипка показывает более подробно недостатки других решений, когда контент попадает в центральные divs.

<style>
    div { margin: 5px; padding: 5px; } 
    .js-container { border: 1px solid red; display: table; }
    .with-width { width: 80%; }
    .js-child { border: 1px solid gray; display: table-cell; }
    .left,
    .right { width: 100px; }
</style>

<h3>Using javascript to dynamically distribute the remaining width</h3>
<div class="js-container with-width">
    <div class="js-child left">left</div>
    <div class="js-child center">center</div>
    <div class="js-child center">center</div>
    <div class="js-child right">right</div>
</div>
<div class="js-container with-width">
    <div class="js-child left">left</div>
    <div class="js-child center">center left <em>doesn't get wider</em> because of extra content</div>
    <div class="js-child center">center right</div>
    <div class="js-child right">right</div>
</div>
<script>
    $(document).ready(function() {
        function containerWidth() {
            var w = parseInt($('.js-container').outerWidth(), 10);
            return w;
        }
        // console.log('containerWidth: ' + containerWidth());
        function outerChildrenWidth() {
            var wl = parseInt($('.js-container').find('.left').outerWidth(), 10);
            var wr = parseInt($('.js-container').find('.right').outerWidth(), 10);
            return wl + wr; // bonus #1
        }
        // console.log('outerChildrenWidth: ' + outerChildrenWidth());
        function centerChildWidth() {
            var w = (containerWidth() - outerChildrenWidth()) / 2; // bonus #2
            return w;
        }
        // console.log('centerChildWidth: ' + centerChildWidth());
        function setCenterChildWidth() {
            $('.js-container').find('.center').css('width', centerChildWidth() + 'px');
        }
        setCenterChildWidth();
    });
</script>

Обратите внимание, что префикс js- для некоторых классов существует, потому что я использовал его для разделения разметки, зависящей от javascript, от "нормального". Я также сохраняю консольные журналы в случае, если вы хотите отлаживать.

Ответ 8

Если вы знаете ширину DIV1 и DIV4, попробуйте найти ширину другие два div в%.try, чтобы дать ширину в% к DIV2 и DIV3.IT будет работа.