如何强制一个浮动的DIV与另一个浮动的DIV匹配高度?

68

我的HTML代码只是将页面分成两栏,分别为65%和35%。

<div style="float : left; width :65%; height:auto;background-color:#FDD017;">
   <div id="response">
   </div> 
</div>
<div style="float : left; width :35%;height:auto; background-color:#FDD017;">
   <div id="note">
   </div>
</div> 
在“响应”div中,我有可变的数据;在“注释”div中,我有固定的数据。 尽管这两个div具有不同的数据集,但我需要它们以相同的高度显示,以便背景颜色看起来填充包含两者的框。自然而然的问题是“响应”div,因为它的高度取决于当前在其中显示的数据量。 我该如何确保这两列的高度始终相等?
11个回答

99

将它们包裹在一个含有背景颜色的容器div中,然后在“列”之后加入一个清除div。

<div style="background-color: yellow;">
  <div style="float: left;width: 65%;">column a</div>
  <div style="float: right;width: 35%;">column b</div>
  <div style="clear: both;"></div>
</div>

更新以解决一些评论和我的想法:

这种方法之所以有效,是因为它本质上是对您的问题进行简化。在这种“老派”的方法中,我放置了两个列,然后是一个空的清除元素,清除元素的作用是告诉父元素(具有背景)这是浮动行为结束的位置,这允许父元素在清除位置实际呈现零像素高度,这将是先前最高的浮动元素。

这样做的原因是确保父元素的高度与最高的列相同,然后在父元素上设置背景,以使两个列具有相同的高度外观。

值得注意的是,这种技术是“老派”的,因为更好的选择是使用类似于clearfix这样的东西触发此高度计算行为,或者只需在父元素上设置overflow:hidden。

虽然这在这种有限的场景中可以使用,但如果您希望每个列看起来不同,或者它们之间有间隙,则在父元素上设置背景将无效,但是有一种技巧可以实现这种效果。

技巧是向所有列添加底部填充,最大的大小是您预计最短和最高列之间可能存在的差异,如果您无法计算出这个值,请选择一个较大的数字,然后需要添加相同数量的负底部边距。

您需要在父对象上设置overflow hidden,但结果将是每个列都将请求呈现由边距建议的额外高度,但实际上不会请求该大小的布局(因为负边距抵消了计算)。

这将使父元素呈现为最高的列的大小,同时允许所有列以其高度+所使用的底部填充的大小呈现,如果此高度大于父元素,则其余部分将简单地被修剪掉。

<div style="overflow: hidden;">
  <div style="background: blue;float: left;width: 65%;padding-bottom: 500px;margin-bottom: -500px;">column a<br />column a</div>
  <div style="background: red;float: right;width: 35%;padding-bottom: 500px;margin-bottom: -500px;">column b</div>
</div>
您可以在Bowers & Wilkins网站上看到此技术的示例(请查看页面底部的四个水平聚光灯图像)。

3
如果两列有不同的背景颜色,这样做就没有帮助。 - Arve Systad
13
他的例子没有这个要求,谢谢你的负评 :). - meandmycode
我知道这已经很老了,但还是点个赞。你能解释一下为什么这个方法有效吗? - Parris Varney
在我正在忙碌的一个项目上,它对我非常完美无缺。谢谢。点赞! - user305054
+1 我的朋友;我简直不敢相信这个修复如此快速简单,但我自己却想不到。 - lxndr
显示剩余4条评论

38
如果您想强制一个浮动的div与另一个匹配以创建列效果,这是我所做的。我喜欢它,因为它简单而干净。
<div style="background-color: #CCC; width:300px; overflow:hidden; ">
    <!-- Padding-Bottom is equal to 100% of the container's size, Margin-bottom hides everything beyond
         the container equal to the container size. This allows the column to grow with the largest
         column. -->
    <div style="float: left;width: 100px; background:yellow; padding-bottom:100%; margin-bottom:-100%;">column a</div>
    <div style="float: left;width: 100px;  background:#09F;">column b<br />Line 2<br />Line 3<br />Line 4<br />Line 5</div>
    <div style="float:left; width:100px; background: yellow; padding-bottom:100%; margin-bottom:-100%;">Column C</div>
    <div style="clear: both;"></div>
</div>

我认为这很有道理。即使是动态内容,它似乎也能很好地工作。


是的,100%听起来比一个非常高的固定数字好多了。谢谢这个建议。 - Jags
3
问题在于我想让每一列都有一个边框,但这样会隐藏底部的边框。:( - Alexander Bird
在尝试了一些实验后,我注意到填充的百分比值实际上是基于元素的宽度计算的,因此在纵向视图中可能需要超过100%(有趣的技巧+1)。请参阅mdn - stianlik
这种技术的一个非常好的方面是它似乎与Foundation等CSS框架高度兼容。此外,它不会影响在移动视图中将矩阵压缩为单列。总的来说,我认为这是#1解决方案。 - Chris Marisic
有一件事...你可以在父元素上添加一个 :after,而不是使用 <div style="clear: both;"></div>。这样可以消除无意义的标记。 - Katherine C
这似乎无法与 vertical-align: center; 一起使用,有什么想法如何修复? - Dan Bechard

15

这里有一个jQuery插件可以将多个div的高度设置成相同。以下是该插件的实际代码。

$.fn.equalHeights = function(px) {
$(this).each(function(){
var currentTallest = 0;
$(this).children().each(function(i){
    if ($(this).height() > currentTallest) { currentTallest = $(this).height(); }
        });
    if (!px || !Number.prototype.pxToEm) currentTallest = currentTallest.pxToEm(); //use ems unless px is specified
        // for ie6, set height since min-height isn't supported
    if ($.browser.msie && $.browser.version == 6.0) { $(this).children().css({'height': currentTallest}); }
        $(this).children().css({'min-height': currentTallest}); 
    });
    return this;
};

2
根据设计,使用类似这样的JavaScript可能是唯一的选择。 - Johan Kronberg
1
纯CSS解决方案很少用,因为它们适用于简单的设计。我通常使用这样的脚本。但在处理AJAX时应该小心。 - Eastern Monk
1
如果你遇到了和我一样的问题,可以使用 if (!px && Number.prototype.pxToEm) 来解决它。 - lsl
4
请问 AJAX?请告诉我这个回答中哪里有异步 JavaScript。 - gok
@ChrisMarisic,你打错字了:“通常被认为是如果您选择分发网站,则必须开源整个网站。即使如此,您也不需要将其提供下载--只需在有人想要通过传真获取并愿意支付您的“源代码处理、复制和56k传真调制解调器费用”时可用即可。 - dhaupin
显示剩余3条评论

10

解决这个问题的正确方法是使用display: table-cell

重要提示:这个解决方法不需要使用float,因为table-cell已经将div转变为了与同一容器中的其他元素对齐的元素。这也意味着你不必担心清除浮动、溢出、背景透亮以及所有其他由float hack 带来的讨厌惊喜。

CSS:

.container {
  display: table;
}
.column {
  display: table-cell;
  width: 100px;
}

HTML:

<div class="container">
    <div class="column">Column 1.</div>
    <div class="column">Column 2 is a bit longer.</div>
    <div class="column">Column 3 is longer with lots of text in it.</div>
</div>

相关内容:


6

你应该将它们包裹在一个没有浮动的 div 中。

<div style="float:none;background:#FDD017;" class="clearfix">
    <div id="response" style="float:left; width:65%;">Response with two lines</div>
    <div id="note" style="float:left; width:35%;">single line note</div>
</div>

我也在这里使用clearfix补丁http://www.webtoolkit.info/css-clearfix.html


2
如果两列具有不同的背景颜色,则无法帮助。除非您知道其中一列始终比另一列长:将“包装器”的背景颜色设置为最短列的颜色,并让最长的列具有自己的背景颜色以“伪造”两个等长的列。 - Arve Systad
@Arve Systad同意,这似乎不是OP正在寻找的。 - bendewey
如果我想为每个div使用两种不同的颜色怎么办? - Vixed

4

我无法理解为什么这个问题一直被反复强调,因为在30秒内您可以编写一个双列表格并解决问题。

在典型的布局中,这个div列高度问题经常出现。为什么要使用脚本,当一个普通的基本HTML标签就能解决呢?除非在布局中有大量且数量众多的表格,否则我不相信表格会显著变慢。


大多数用户都知道“基于 div 的布局”是热门趋势,并告诉我们不要使用表格。我们遇到过许多客户,他们希望在所有设计布局中都不使用表格。 - Eastern Monk
10
表格用于表格,CSS用于布局。这个问题很简单,但解决方案应该适用于任何复杂度。如果我有一个16列的布局怎么办?我可以使用一个16列的表格,但当我想要改变网站的样式时呢?我的代码会变得一团糟。 - Marek Maurizio

1

0

这段代码将允许您拥有可变数量的行(每行具有可变数量的DIV),并使每行中的所有DIV与其最高邻居的高度相匹配:

如果我们假设所有浮动的DIV都在一个名为“divContainer”的容器内,那么您可以使用以下代码:

$(document).ready(function() {

var currentTallest = 0;
var currentRowStart = 0;
var rowDivs = new Array();

$('div#divContainer div').each(function(index) {

    if(currentRowStart != $(this).position().top) {

        // we just came to a new row.  Set all the heights on the completed row
        for(currentDiv = 0 ; currentDiv < rowDivs.length ; currentDiv++) rowDivs[currentDiv].height(currentTallest);

        // set the variables for the new row
        rowDivs.length = 0; // empty the array
        currentRowStart = $(this).position().top;
        currentTallest = $(this).height();
        rowDivs.push($(this));

    } else {

        // another div on the current row.  Add it to the list and check if it's taller
        rowDivs.push($(this));
        currentTallest = (currentTallest < $(this).height()) ? ($(this).height()) : (currentTallest);

    }
    // do the last row
    for(currentDiv = 0 ; currentDiv < rowDivs.length ; currentDiv++) rowDivs[currentDiv].height(currentTallest);

});
});

0
我建议您将它们都包裹在一个外层 div 中,使用所需的背景颜色。

0

你也可以随时使用背景图片来实现它。我倾向于100%支持这个选项,因为唯一的其他完美解决方案是Jquery选项。

与使用具有背景颜色的外部div一样,您最终将不得不使两个div中的内容达到相同的高度。


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