如何在div中将高度可变的内容垂直居中?


158

当内容的高度可变时,垂直对齐div内容的最佳方法是什么?在我的特定情况下,容器div的高度是固定的,但是如果有一种在容器高度可变的情况下也能起作用的解决方案,那会很棒。另外,我希望不使用CSS hack和/或使用非语义标记,或者很少使用CSS hack和/或非语义标记的解决方案。

替代文字


该文章中的方法在Safari(4.0.5)中崩溃了:S

7
@ ripper234不完全是,因为这个问题是关于可变高度div的
Rauli Rajande 2013年

9
另外,首先问了这个问题。
2014年

Answers:


147

只需添加

position: relative;
top: 50%;
transform: translateY(-50%);

到内部div

它所做的是将内部div的顶部边框移到外部div的一半高度(top: 50%;),然后将内部div向上移动一半其高度(transform: translateY(-50%))。这将与position: absolute或一起使用relative

请记住,transformtranslate具有供应商前缀,为简单起见不包含这些前缀。

Codepen:http://codepen.io/anon/pen/ZYprdb


6
只是想知道为什么它可以在Chrome和Firefox上运行,但不适用于Safari。然后我注意到大多数transform相关的内容-webkit-都已加上前缀,现在可以使用了。提醒一下:不要忘记添加-webkit-前缀。
miho 2015年

5
使用github.com/postcss/autoprefixer之类的工具为您处理前缀。
Jamie Chong

6
这个答案应该在顶部。
Jose Faeti 2015年

3
这应该有更多的支持!顺便说一句,它也可以使用position: absolute,不是吗?
caw

4
此方法在Chrome中有一个不幸的副作用-如果包装器的像素数为奇数,则translate在尝试处理所有内容的.5px高度时,所有内容都会变得模糊。
基思

157

只要您的浏览器支持以下::before伪元素,这似乎就是我找到的最佳解决方案:CSS-Tricks:居中于Unknown

它不需要任何额外的标记,并且看起来非常好用。我不能使用该display: table方法,因为table元素不服从max-height属性。

.block {
  height: 300px;
  text-align: center;
  background: #c0c0c0;
  border: #a0a0a0 solid 1px;
  margin: 20px;
}

.block::before {
  content: '';
  display: inline-block;
  height: 100%; 
  vertical-align: middle;
  margin-right: -0.25em; /* Adjusts for spacing */

  /* For visualization 
  background: #808080; width: 5px;
  */
}

.centered {
  display: inline-block;
  vertical-align: middle;
  width: 300px;
  padding: 10px 15px;
  border: #a0a0a0 solid 1px;
  background: #f5f5f5;
}
<div class="block">
    <div class="centered">
        <h1>Some text</h1>
        <p>But he stole up to us again, and suddenly clapping his hand on my
           shoulder, said&mdash;"Did ye see anything looking like men going
           towards that ship a while ago?"</p>
    </div>
</div>


3
现在-that-是-BRILLIANT-解决方案。非常感谢您发布此信息!
Troy Alford 2012年

与其他答案一样,如果它描述了这种方法并包含了链接中的代码,则效果会更好。
KatieK

3
+1,这个解决方案真的很巧妙!顺便说一句,您可以.block { white-space: nowrap; font-size: 0; line-height: 0; }在伪元素上添加并保留负右边界,只需在.centered上重置fs和lh即可。这样,即使元素的宽度大于视口,也可以确保其正确定位(并且不要不必使用imo有点乱的负边距)。
西蒙(Simon)

@jessegavin -在你看来...如何将下面的堆栈起来反对你介绍的方法:stackoverflow.com/questions/396145/...
pulkitsinghal

1
另外,当外部容器.block具有最小高度而不是高度时,此方法将失效。
林肯B

16

这是我多次需要做的事情,并且一致的解决方案仍然需要您添加一些非语义标记和一些特定于浏览器的技巧。当我们获得浏览器对CSS 3的支持时,您将获得垂直居中的位置,而不会犯罪。

为了更好地解释该技术,您可以看一下我改编自该文章的文章,但基本上,它涉及在IE和支持position:table\table-cell非表元素的浏览器中添加额外的元素并应用不同的样式。

<div class="valign-outer">
    <div class="valign-middle">
        <div class="valign-inner">
            Excuse me. What did you sleep in your clothes again last night. Really. You're gonna be in the car with her. Hey, not too early I sleep in on Saturday. Oh, McFly, your shoe's untied. Don't be so gullible, McFly. You got the place fixed up nice, McFly. I have you're car towed all the way to your house and all you've got for me is light beer. What are you looking at, butthead. Say hi to your mom for me.
        </div>
    </div>
</div>

<style>
    /* Non-structural styling */
    .valign-outer { height: 400px; border: 1px solid red; }
    .valign-inner { border: 1px solid blue; }
</style>

<!--[if lte IE 7]>
<style>
    /* For IE7 and earlier */
    .valign-outer { position: relative; overflow: hidden; }
    .valign-middle { position: absolute; top: 50%; }
    .valign-inner { position: relative; top: -50% }
</style>
<![endif]-->
<!--[if gt IE 7]> -->
<style>
    /* For other browsers */
    .valign-outer { position: static; display: table; overflow: hidden; }
    .valign-middle { position: static; display: table-cell; vertical-align: middle; width: 100%; }
</style>

在特定的浏览器集中应用样式的方法有很多(技巧)。我使用了条件注释,但请看上面链接的文章,以了解其他两种技术。

注意:如果您事先知道一些高度,试图将一行文本居中,或者在其他几种情况下,有几种简单的方法可以使垂直居中。如果您有更多详细信息,请把它们放进去,因为可能有一种方法不需要浏览器入侵或非语义标记。

更新:我们开始获得对CSS3更好的浏览器支持,将flex-box和transforms作为获取垂直居中的替代方法(包括其他效果)。有关现代方法的更多信息,请参见另一个问题,但请记住,对于CSS3来说,浏览器支持仍然是粗略的。


是的,我今天发现了这篇文章,但未能使其适合我的特定情况。也许我需要进一步研究。
jessegavin

也许您可以发布您正在使用的代码而无法正常工作?
克里斯·马拉斯蒂·乔治

这仍然是解决此问题的最佳方法吗?
ripper234

该文章似乎不适用于Chrome 23,Firefox 16和IE9。此答案似乎是一个更好的解决方案。
费尔南多·科雷亚

不,截至2013
OMA

9

使用子选择器,我已经接受了Fadi上面令人难以置信的答案,并将其简化为我可以应用的一个CSS规则。现在,我要做的就是将contentCentered类名称添加到我要居中的元素中:

.contentCentered {
  text-align: center;
}

.contentCentered::before {
  content: '';
  display: inline-block;
  height: 100%; 
  vertical-align: middle;
  margin-right: -.25em; /* Adjusts for spacing */
}

.contentCentered > * {
  display: inline-block;
  vertical-align: middle;
}
<div class="contentCentered">
  <div>
    <h1>Some text</h1>
    <p>But he stole up to us again, and suddenly clapping his hand on my
      shoulder, said&mdash;"Did ye see anything looking like men going
      towards that ship a while ago?"</p>
  </div>
</div>

分叉的CodePen:http ://codepen.io/dougli/pen/Eeysg


凉。感谢分享。注意事项之一是*选择器的性能将比可接受的答案差。可能不是问题,但值得注意。 stevesouders.com/blog/2009/06/18/simplifying-css-selectors
jessegavin 2013年

谢谢。是的,它的性能可能会更差,但是如今,CSS规则可能不会对其产生太大影响。我们可以通过选择on > div来改善它。calendar.perfplanet.com/2011/...
dougli

简单而伟大。非常适合我。
Lovro


3

您可以使用保证金自动。使用flex时,div似乎也垂直居中。

body,
html {
  height: 100%;
  margin: 0;
}
.site {
  height: 100%;
  display: flex;
}
.site .box {
  background: #0ff;
  max-width: 20vw;
  margin: auto;
}
<div class="site">
  <div class="box">
    <h1>blabla</h1>
    <p>blabla</p>
    <p>blablabla</p>
    <p>lbibdfvkdlvfdks</p>
  </div>
</div>

display:flex实际上仍是一项实验功能;没有浏览器suports它正确尚未
andreszs


0

对于div具有动态(百分比)高度的,这是我的出色解决方案。

的CSS

.vertical_placer{
  background:red;
  position:absolute; 
  height:43%; 
  width:100%;
  display: table;
}

.inner_placer{  
  display: table-cell;
  vertical-align: middle;
  text-align:center;
}

.inner_placer svg{
  position:relative;
  color:#fff;
  background:blue;
  width:30%;
  min-height:20px;
  max-height:60px;
  height:20%;
}

的HTML

<div class="footer">
    <div class="vertical_placer">
        <div class="inner_placer">
            <svg> some Text here</svg>
        </div>
    </div>
</div>  

自己尝试。


0

您可以使用弹性显示,例如以下代码:

.example{
  background-color:red;
  height:90px;
  width:90px;
  display:flex;
  align-items:center; /*for vertically center*/
  justify-content:center; /*for horizontally center*/
}
<div class="example">
    <h6>Some text</h6>
</div>

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.