如何垂直居中浮动元素,且高度未知?

47

我有一个水平居中的外部 div,其中包含两个宽度未知的元素:

<div style='width:800px; margin:0 auto'>
  <div style='float:left'>...</div>
  <div style='float:right'>...</div>
</div>

默认情况下,两个浮动元素是顶部对齐的,且它们高度不同或未知。有没有办法垂直居中它们?

最终我将外部div设为:

display: table

以及内部的div元素

display: table-cell;
vertical-align: middle;
text-align: left/right;

但我只是好奇是否有一种方法可以使用浮点数实现这个功能。


13
HTML/CSS中的垂直对齐实在太丑陋了,是我强烈想要用IE6的腐烂尸体抽打整个W3C并喂给他们的主要原因。 - Marc B
2
@MarcB 你并不孤单,但这就是我们必须处理的问题... - Yang
3个回答

60
您不能直接这样做,因为浮动会对齐到顶部:

如果有行框,则浮动框的外部顶部与当前行框的顶部对齐。

精确的规则是(重点在于我):
  1. 浮动框的外顶部不能高于其包含块的顶部。
  2. 浮动框的外顶部不能高于源文档中任何一个元素生成的浮动框的外部顶部。
  3. 元素的浮动框的外顶部不能高于源文档中任何一个元素生成的包含框中包含的任何行框的顶部。

  1. 浮动框必须尽可能地高。

话虽如此,您可以利用第四条规则:

  • 将每个浮动元素放置在内联级别元素中,以建立新的块格式化上下文(BFC),例如display: inline-block
  • 这些包装器将包含浮动元素,因为它们建立了BFC,并且将彼此相邻,因为它们是内联级别的。
  • 使用vertical-align来垂直对齐这些包装器。

请注意,在内联块包装器之间可能会出现一些空间。请参见如何删除内联块元素之间的空格?进行修复。

.float-left {
  float: left;
}

.float-right {
  float: right;
}

#main {
  border: 1px solid blue;
  margin: 0 auto;
  width: 500px;
}

/* Float wrappers */
#main > div {
  display: inline-block;
  vertical-align: middle;
  width: 50%;
}
<div id="main">
  <div>
    <div class="float-left">
      <p>AAA</p>
    </div>
  </div>
  <div>
    <div class="float-right">
      <p>BBB</p>
      <p>BBB</p>
    </div>
  </div>
</div>


9
这个解决方案可行是因为您加入了 width:49%;,即使没有浮动的 div 也会起作用。 - Hayi
10
我意识到这确实有应用,但对我来说似乎有些作弊。float: right 在这里唯一的作用就是右对齐 BBB 内容。实际上,是 display: inline-blockvertical-align: middle 实现了居中对齐。 它并没有真正垂直居中浮动内容。 - Simon_Weaver
5
这里根本不应该使用浮动。它除了像@Simon_Weaver提到的那样用于调整内容位置外没有其他作用。相反,最好使用text-align: right,这样div的高度将成为页面流的一部分,无需使用clearfix。 - newms87
3
可能是真的。但那样就不会有任何小数,因此它不能回答这个问题。现在我认为我已经回答了它,即使我有点作弊。 - Oriol
1
如果父元素有明确的高度,您可以插入一个带有 height: 100%vertical-align: middle在未知中居中 技术)的内联级伪元素来实现居中。 - Oriol
显示剩余3条评论

10
另一种方法是使用flex——如果您有两个部分,则可以替代float。一个(浮动)为自动大小,另一个将增长以占用整个容器。在交叉轴上,选择center,然后就可以获得浮动和居中元素的效果
这里有一个关于flex的漂亮备忘单:http://jonibologna.com/flexbox-cheatsheet/

2
当你尝试使用flex时,当然会遇到IE的恐怖。 :-| - T.J. Crowder
1
那张速查表非常有用。 - Ghost Echo

3

如果表格的单元格是固定高度的,可以使用行高来实现。


如果有人对使用表格进行布局过敏,CSS表格也可以使用(尽管在底层仍然是表格)。 - jahu
如果您想要一个自然流动的响应式布局,在较窄的视口下显示在左侧元素下方,那么表格并不是很好的选择。 - Joel Coehoorn
@JoelCoehoorn那完全不正确,如果你正在使用CSS表格。只需在正确的CSS查询中需要时将表格显示更改为块显示即可。 - NoobishPro
@Babydead 整个表格...没问题。但是对于同一行中的单个 td 元素,这很奇怪。 - Joel Coehoorn
当然。不过,表的理念是以相同的方式呈现所有数据。我想不到有什么情况需要元素在响应式时与其他元素的行为有所不同,当它们在非响应式形式中对齐时也是如此。我已构建了超过250个响应式网站,从未遇到过这样的问题。如果您有例子,我很想看看。非常好奇! - NoobishPro

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