将一个 div 扩展以填充剩余的宽度

654

我想要一个两列div布局,每个列的宽度可以是不同的,例如:

div {
  float: left;
}

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

我希望'view' div在'tree' div填充所需空间后可以扩展到整个可用宽度。

目前,我的'view' div被调整为适应其包含的内容。 如果两个div都占据整个高度,那将更好。


非重复声明:


1
要么我不理解这个问题,要么我不明白你是如何选择被接受的答案的,因为在这里宽度和高度都是固定的,而且还有“溢出隐藏”的不便。 - user10089632
@user10089632 这是行为的正确解释,而当时像 flexbox 这样更好的解决方案还不可用。 - TylerH
21个回答

1087
这个问题的解决方案非常简单,但并不明显。您需要触发一个叫做“块级格式化上下文”(BFC)的东西,它以特定的方式与浮动交互。
只需将第二个 div 删除浮动,并改为使用overflow:hidden。除了 visible 之外的任何 overflow 值都会使其所在的块成为 BFC。BFC 不允许后代浮动元素逃脱,也不允许同级/祖先浮动元素侵入其中。这里的净效果是:浮动的 div 将执行其任务,然后第二个 div 将成为普通块,占据除浮动元素占用的所有可用宽度之外的所有空间。
这应该适用于所有当前的浏览器,尽管您可能需要在 IE6 和 7 中触发 hasLayout。我记不清了。
演示:
- 固定左侧:http://jsfiddle.net/A8zLY/5/ - 固定右侧:http://jsfiddle.net/A8zLY/2/

div {
  float: left;
}

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


2
如果内容足够大以至于溢出div怎么办? - giannis christofakis
1
好的回答。但是为什么“float: right”不适用于同样的原则呢? - Andrade
2
错误的。如果没有“overflow”(或其他触发BFC的手段),变长的div将无法“避免”另一个div。它的文本将避开浮动的div,但其背景/边框/等将包含它们,这可能不是想要的结果。 - Xanthir
13
需要注意的是,孩子节点的顺序很重要。具有固定宽度的浮动元素必须位于另一个元素的上方。我曾经尝试过更改顺序,但花费了太长时间才弄清楚为什么它对我不起作用。 - Riplexus
2
我写了一个回答,解释为什么所有事物的不可见溢出会触发BFC,这是基于David和Boris提供的回答,可以在这里找到:https://dev59.com/wmkw5IYBdhLWcg3wXpac#11854515 我的解释正确吗? - BoltClock
显示剩余12条评论

182

我刚刚发现了弹性盒子的神奇之处(display: flex)。试试这个:

<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盒子让我拥有了15年来一直希望CSS具备的控制能力。它终于来了!更多信息:https://css-tricks.com/snippets/css/a-guide-to-flexbox/


1
谢谢。您能否解释一下为什么您使用了 flex-grow: 100; 而不是 flex-grow: 1; - Yevgeniy Afanasyev
10
没有特别的原因,只是我喜欢这样做。这样可以让我以百分比来思考,例如我可以将 #a 设为 flex-grow:10,然后将 #b 设为 flex-grow:90,这样 #a 的宽度就是该行宽度的10%,#b 的宽度就是该行宽度的90%。如果没有其他元素具有 flex 宽度样式,那么你放置的内容在技术上并不重要。 - B T

70

Use the CSS Flexbox flex-grow property to fill the remaining space.

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>


29

这是一个使用表格容易实现但使用CSS很难(如果不是不可能的话,至少在跨浏览器方面)的好例子。

如果两列都是固定宽度,那么这很容易。

如果其中一列是固定宽度,则会稍微困难一些,但完全可行。

对于两列都是可变宽度的情况,我认为需要使用双列表格。


11
如果您想在小设备上让右侧列滑动到左侧列下方,那么表格在响应式设计中可能不是很理想。 - S..
1
有一些响应式设计技巧可以用于处理表格:https://css-tricks.com/responsive-data-tables/ - Rikki
我现在倾向于完全设计两个不同的布局,并使用媒体查询和display:none;在移动设备上进行更改。尽可能地使其100%响应式,有时为了更好地利用触摸屏幕感觉和按钮样式,在移动设备上完全更改设计会更好。 - Bysander

25
使用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可行),或者作为自身明确定义的某些东西的百分比。

这种方法的问题在于,所有的宽度都必须明确定义,要么是一个值(px和em可行),要么是相对于另一些已经被明确定义的东西的百分比。


这样做的好处是它可以与输入类型字段一起使用,而顶级评论则不能。 - Leigh Bicknell

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
这通常是一种更优越的解决方案,因为不总是希望隐藏溢出。 - Joseph Lennox
3
根据原文,OP希望使用两列div布局,并且每一列都可以具有变宽的特性。但是在你的回答中,你需要知道第一列的宽度,因此它不是可变的。实际上,你可以设置两个列的固定宽度并将它们浮动起来。 - Jacob

16
这里可能会有所帮助...

<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 因为你的示例似乎可以工作,但在我的实际场景中,一些来自“视图”的内容会渗入“树”div中,因为树形div不是100%,可能是某些JavaScript强制它变小,在树的高度之后我看到了视图内容。 - Anurag Uniyal
在这种情况下,如果你知道左列的最大宽度,你可以给它一个 max-width 样式(不适用于 IE),或者考虑 margin-left(注意 IE 上的双倍边距错误)或 padding-left。 - a6hi5h3k

9
如果另一列的宽度是固定的,可以考虑使用在所有常见浏览器上都可行的CSS函数calc
width: calc(100% - 20px) /* 20px being the first column's width */

这种方式将计算第二行的宽度(即剩余宽度)并进行响应式应用。


4

我不明白为什么人们愿意花费如此之多的精力来寻找纯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
3
这是因为如果您希望在小设备上使用media-queries将两列放在同一行,使用旧的table标签是不可能的。要让它起作用,您需要应用CSS表格样式。因此,在现今,如果您想要适应任何屏幕大小的响应式布局,最好使用CSS来解决这个问题。 - ElChiniNet
因为表格是用于表格内容的。OP没有表格内容;他们有两个带有未知内容的div。 - TylerH

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; white-space: nowrap; overflow: hidden; text-overflow:clip - englebart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接