HTML/CSS:如何使两个浮动的div高度相同

109

我目前有一个有些奇特的问题,使用 table 来解决,如下所示。基本上,我想要两个 div 占用 100% 的可用宽度,但只占用所需的垂直空间(从图片中并不是很明显)。两个 div 应始终具有完全相同的高度,并有一条小线将它们隔开,如图所示。

alt text
(来源:pici.se

这一切都可以使用 table 很容易实现,这也是我目前正在使用的方法。然而,我对这个解决方案并不太感兴趣,因为从语义上讲,这并不是真正的表格。


2
呃...图片在哪里?我知道我太晚评论了。 - Ajay Kulkarni
这是来自WebArchive.org的图片链接:https://web.archive.org/web/20120617031534/http://pici.se/pictures/qJRMtoLPv.png - DidThis
14个回答

166

通过对底部应用大量的底部填充、相同数量的负底边距和将列包围在具有溢出隐藏的div中,可以在CSS中获得等高列。垂直居中文本有点棘手,但这应该可以帮助你解决问题。

#container {
  overflow: hidden;
      width: 100%;
}
#left-col {
  float: left;
  width: 50%;
  background-color: orange;
  padding-bottom: 500em;
  margin-bottom: -500em;
}
#right-col {
  float: left;
  width: 50%;
  margin-right: -1px; /* Thank you IE */
  border-left: 1px solid black;
  background-color: red;
  padding-bottom: 500em;
  margin-bottom: -500em;
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">

<head></head>

<body>
  <div id="container">
    <div id="left-col">
      <p>Test content</p>
      <p>longer</p>
    </div>
    <div id="right-col">
      <p>Test content</p>
    </div>
  </div>
</body>

值得一提的是,之前streetpc所写的答案中html无效,doctype为XHTML并且属性周围有单引号。还值得注意的是,你不需要额外使用带有clear的元素来清除容器内部的浮动。如果您使用overflow:hidden,则会在所有非IE浏览器中清除浮动,然后只需添加某些内容以使其具有hasLayout,例如width或zoom:1将导致IE清除其内部浮动。

我已在所有现代浏览器(FF3+ Opera9+ Chrome Safari 3+和IE6/7/8)中进行了测试。这可能看起来像一个丑陋的技巧,但它非常有效,并且我在生产中经常使用它。


1
我提供的代码在W3C的验证器上通过了验证(当然,一旦你添加了一个<title>元素,这不是你的重点)。此外,根据这个讨论,规范允许使用单引号:http://www.sitepoint.com/forums/showthread.php?t=54273#6 - instanceof me
1
抱歉,我的错误。我已经更正了上面的回答。需要注意的是,如果右列比左列宽,红色会从底部透露出来,因为两个框的高度不完全相同。根据设计风格,我会选择使用人造列或者使用底部边距和填充的方法。 - Natalie Downe
2
实际上,虽然Kevin C.提供的关于阴影被切断的解决方案适用于顶部、左侧和右侧填充,但它不适用于底部。到目前为止还没有找到解决办法。 - JeanMertz
1
干得好,Natalie。@laarsk,不可预测的高度正是这个的作用,不是吗?请参见演示:http://jsfiddle.net/RT3MT/4/移动“更长”的段落以查看。 - jpillora
1
这是我见过的最丑陋的CSS hack之一,但我会开怀接受它哈哈。似乎这是唯一的前进之路。 - Matt Vukas
显示剩余6条评论

100

33
当这个答案被替换为 display: flex 的时候,是哪一年? - LandonSchropp
12
不,现在是2014年。 - Francisco Presencia
9
2015年了,也许到年底时我们可以改变答案,使用"display:flex"来展示。 - MetalWeirdo
5
我仍然生活在20世纪50年代。 - Jay
1
2017年 #首篇 :) - Geoffrey Hale
显示剩余15条评论

22

你应该使用flexbox来实现此目的。它不支持IE8和IE9,只在IE10中使用-ms前缀,但所有其他浏览器都支持它。对于供应商前缀,你也应该使用autoprefixer

.parent {
    display: flex;
    flex-wrap: wrap; // allow wrapping items
}

.child {
    flex-grow: 1;
    flex-basis: 50%; // 50% for two in a row, 33% three in a row etc.
}

1
我对Flex的问题在于它需要在列周围添加包装器。使用浮动+display:table技术,我可以拥有一个标题和一堆列,效果作用于列而不影响标题。 - Stijn de Witt

10

您可以使用JavaScript使其正常工作:

<script>
    $(document).ready(function() {
        var height = Math.max($("#left").height(), $("#right").height());
        $("#left").height(height);
        $("#right").height(height);
    });
</script>

1
请注意,这个问题已经相当老了,并且已经提供了更好的解决方案(无需使用JavaScript)。 - nirazul
1
我实际上喜欢这个解决方案。它有趣且表明您不仅可以使用CSS操纵HTML,还可以借助jQuery完成。 - csichar
6
如果列的高度发生变化,该解决方案将无法正常工作。如果更改列的内容,则可能会发生这种情况。此函数需要在内容更改和浏览器调整大小时运行。采用 CSS 方法更加理想,因为它避免了这些问题。 - alexreardon

5

这是CSS中的一个经典问题。实际上并没有解决方案。

A List Apart的这篇文章很好地阐述了这个问题。它使用一种称为“伪列”的技术,基于在包含列的元素上放置一个垂直平铺的背景图像,从而创造出等长列的幻觉。由于它在浮动元素的包装器上,所以它与最长元素一样长。


A List Apart编辑对这篇文章有以下注释:

编辑注:虽然在其时代非常优秀,但这篇文章可能不反映现代最佳实践。

该技术需要完全静态宽度设计,不适用于流式布局和响应式设计技术,这些技术在跨设备站点中非常流行。但对于静态宽度站点来说,它是可靠的选择。


谢谢,那看起来是个不错的技巧。但是,我忘了提到右列应该有文字,并且垂直居中。我认为伪列无法做到这一点,我的想法正确吗? - Deniz Dogan

4

我曾遇到类似问题,个人认为最好的选择是使用少量的javascript或jquery。

您可以通过获取最高的div值并将该值应用于所有其他div来使所需的div具有相同的高度。如果您有很多div和许多解决方案,建议编写一些高级js代码来找出所有div中最高的那个,然后使用它的值。

使用jquery和2个div非常简单,以下是示例代码:

$('.smaller-div').css('height',$('.higher-div').css('height'));

最后,还有一件事情。 它们的填充(上下)必须相同!如果一个填充较大,您需要消除填充差异。


1

这在IE 7、FF 3.5、Chrome 3b和Safari 4(Windows)中对我有效。

如果您取消底部的清除div,它也适用于IE 6。 编辑:正如Natalie Downe所说,您可以简单地将#container添加width: 100%;

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <style type="text/css">
        #container {
            overflow: hidden;
            border: 1px solid black;
            background-color: red;
        }
        #left-col {
            float: left;
            width: 50%;
            background-color: white;
        }
        #right-col {
            float: left;
            width: 50%;
            margin-right: -1px; /* Thank you IE */
        }
    </style>
</head>
<body>
    <div id='container'>
        <div id='left-col'>
            Test content<br />
            longer
        </div>
        <div id='right-col'>
            Test content
        </div>
        <!--div style='clear: both;'></div-->
    </div>
</body>
</html>

如果右侧的 div 没有固定高度,我不知道有什么 CSS 方法可以垂直居中文本。如果有固定高度,您可以将 line-height 设置为与 div 高度相同的值,并使用 display: inline; line-height: 110% 包含文本的内部 div。


1
通过使用CSS属性 --> display:table-cell,可以将元素设置为表格单元格。

div {
    border: 1px solid #000;
    margin: 5px;
    padding: 4px;
 display:table-cell;
 width:25% ;position:relative;
}
body{display:table;
 border-collapse:separate;
 border-spacing:5px 5px}
<div>
    This is my div one This is my div one This is my div one
</div>
<div>
    This is my div two This is my div two This is my div two This is my div two This is my div two This is my div two
</div>
<div>
    This is my div 3 This is my div 3 This is my div 3 This is my div 3 This is my div 3 This is my div 3 This is my div 3 This is my div 3 This is my div 3 This is my div 3 This is my div 3 This is my div 3
</div>


1
据我所知,您无法使用当前的CSS实现此操作。要使两栏具有相等的高度,您需要使用JS。

1
使用Javascript,您可以使两个div标签的高度相同。较小的div将使用下面显示的代码调整为与最高的div标签相同的高度:
var rightHeight = document.getElementById('right').clientHeight;
var leftHeight = document.getElementById('left').clientHeight;
if (leftHeight > rightHeight) {
document.getElementById('right').style.height=leftHeight+'px';
} else {
document.getElementById('left').style.height=rightHeight+'px';
}

使用“left”和“right”作为div标签的id。

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