展开div以填充剩余宽度


552

我想要一个两列的div布局,其中每个可以具有可变的宽度,例如

div {
  float: left;
}

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

我希望'view'div扩展到'tree'div已填充所需空间后的整个宽度。

目前,我的“视图” div已调整为包含它的内容的大小,如果两个div都占据整个高度,那也将很好。


不重复免责声明:



1
我不明白这个问题,或者我不明白您如何选择接受的答案,因为宽度和高度都因不便而固定了overflow hidden
user10089632

Answers:


1013

这个问题的解决其实很容易,但不是在所有明显。您必须触发一种称为“块格式设置上下文”(BFC)的东西,它以特定的方式与浮点数交互。

只是第二个div,删除浮点数,然后overflow:hidden改用它即可。除可见之外的任何溢出值都会使设置的块成为BFC。BFC不允许子代浮动对象逃脱它们,也不允许同级/祖先浮动对象入侵它们。最终的效果是,浮动div将执行其操作,然后第二个div将是一个普通块,占用所有可用宽度,但不包括float占用的宽度。

尽管您可能必须在IE6和7中触发hasLayout,但它可以在所有当前浏览器上正常工作。我不记得了。

演示:


28
很好的答案!但是,当您说“除auto以外的任何溢出值”将其设为BFC时,您错了。您的意思是除默认值(可见)以外的任何溢出值都将使其变为BFC。实际上,溢出自动也可以很好地工作-这就是我的建议(以防万一您确实有相对定位的元素可能会从该div中窥视)。
英国电信

52
这篇文章有一个很好的解释:colinaarts.com/articles/the-magic-of-overflow-hidden
Max Cantor

1
如果内容足够大以致div溢出怎么办?
giannis christofakis 2012年

11
重要的是要注意,孩子的顺序很重要。具有固定宽度的浮动元素必须在另一个之上。花了我很长时间才弄清楚,为什么它对切换顺序不起作用。
Riplexus

2
我写了一个答案,根据大卫和鲍里斯(David and Boris)给出的回答,解释了为什么一切不可见的溢出会触发BFC,可以在以下位置找到:stackoverflow.com/questions/9943503 / ...我的解释正确吗?
BoltClock

104

我刚刚发现了弹性盒的魔力(显示:弹性)。尝试这个:

<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 Box给了我希望CSS拥有15年的控制权。它终于在这里!更多信息:https : //css-tricks.com/snippets/css/a-guide-to-flexbox/


我不知道您发现了什么,但您的代码在最新的Chrome浏览器中无法正常运行jsfiddle.net/fjb548kw/3
Yevgeniy Afanasyev,

@YevgeniyAfanasyev我删除了“ float:left;” 解决此问题。感谢您的来信!
英国电信

谢谢。您能解释一下为什么要flex-grow: 100;代替flex-grow: 1;吗?
Yevgeniy Afanasyev '18年

2
@YevgeniyAfanasyev没有特别的原因,除了那就是我喜欢这样做的方式。它允许我以百分比为单位进行思考,因此,如果我可以像将#a设置为flex-grow:10然后将#b设置为flex-grow: 90那样,则#a将为线宽的10%,而#b将为线宽的90%。如果没有其他元素具有可弯曲宽度样式,那么从技术上讲,您放置什么都没有关系。
英国电信

这对我来说效果最好,试图将输入和按钮并排放置,就好像它们是一个。
Souleste

28

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很难(如果不是不可能的话,至少在跨浏览器的意义上)很难做到。

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

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

由于两列的宽度都可变,恕我直言,您只需要使用两列表格即可。


11
在响应式设计中,Table并不是一个很好的选择,在这种设计中,您希望右侧列在小型设备上滑到左侧下方。
S..

1
有一些使用表的响应式设计技巧:css-tricks.com/sensitive-data-tables
Rikki

我现在倾向于经常完全设计两个单独的布局,并使用媒体查询在移动设备上进行更改,display:none;虽然尽可能以滑动比例做出100%响应,但有时最好还是完全改变设计以在移动设备上利用触摸屏的感觉和按钮样式。
Bysander

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

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是因为您的示例似乎可行,但在我的实际情况下,由于“树” div不是100%,所以某些情况下“视图”中的内容如何爬行到“树” div中,可能是一些JavaScript强制将其变小并且在树的高度之后我看到了查看内容
阿努拉格环球(09年

在这种情况下,如果您知道左列的最大宽度,则可以给它一种样式最大宽度(在IE中不起作用),也可以考虑使用margin-left(当心IE上的双重利润错误)或向左填充。
2009年

太好了!我将其作为一种一次性解决方案在线使用:<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 2010年

2
这是因为如果要media-queries在小型设备中将两列都放在另一列之上,则使用旧table标记是不可能的。要使此工作正常,您需要应用CSS表格样式。因此,如今,CSS如果您想要针对任何屏幕尺寸的自适应布局,最好解决此问题。
ElChiniNet

5

如果另一列的宽度是固定的,那么如何使用适用于所有常见浏览器calcCSS函数:

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; 溢出:隐藏;text-overflow:clip
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-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

帕特-你说得对。这就是为什么该解决方案可以同时满足“恐龙”和同时代人的原因。:)

.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
没有css类.ip的html参考,它在IE7中不起作用
Keith K

1

您可以使用W3的CSS库,其中包含一个名为的类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编辑器


看起来好像只是添加了“溢出:隐藏”,这使它的答案变得更糟了
vpzomtrrfrt

0

我不确定这是否是您所期望的答案,但是为什么不将Tree的宽度设置为“ auto”,而将“ View”的宽度设置为100%?


3
因为那太宽,会使第二个浮点数低于第一个浮点数。
cletus

0

看一下可用的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的人。

就这么简单。


两列都将可变宽度吗?
阿努拉格环球(09年

0

感谢您插入Simpl.css!

记得ColumnWrapper像这样包装所有列。

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

我即将发布Simpl.css的1.0版,所以请帮助传播!


0

我编写了一个从jQuery $(document).ready()调用的javascript函数。这将解析父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>


在添加您的答案之前,您是否已阅读所有之前的答案?似乎没有...
Temani Afif

附带说明,您无需添加,stretch因为它是默认值,无需创建子元素flex容器,因此display:flex对于内部元素没有用
Temani Afif

我不知道为什么要投反对票,而没有任何评论。这个答案不是对问题的答复吗?为什么?如果试图帮助他人受到惩罚,我将在下一个答案之前三思而后行
马里奥·巴斯克斯

1
投票结束后,您有两个评论,还不够吗?
Temani Afif

Temari,您检查了我的工具吗?您认为有用吗?可以帮助别人吗?您认为与问题无关吗?您对这个问题的答案在哪里?我看不到 您在这里扮演什么角色?
马里奥·巴斯克斯

-3

如果两个宽度都是可变长度,为什么不通过脚本或服务器端计算宽度呢?

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

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

3
服务器如何知道客户端的布局引擎如何工作?
凯夫

简单:为90%的浏览器开发它:) IE 7 +,FF3 +和Safari支持CSS3。您还可以包括标准IE6 <!-[如果是IE 6]>元素。顺便说一句,哪种浏览器不支持style =“ width:%” ??
amischiefr

我不知道如何在服务器端完成此操作,但是是的,有些javscript可以做到这一点,但是除非CSS / html无法做到,否则我想避免使用它
Anurag Uniyal 09年

不能。因此,如果您希望两者都是动态的,则必须在脚本或服务器端进行。
amischiefr
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.