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

Posted

技术标签:

【中文标题】如何在div中以可变高度垂直居中内容?【英文标题】:How to vertically center content with variable height within a div? 【发布时间】:2010-09-08 17:28:04 【问题描述】:

当内容的高度可变时,将 div 的内容垂直居中的最佳方法是什么。在我的特定情况下,容器 div 的高度是固定的,但是如果有一种解决方案可以在容器也具有可变高度的情况下工作,那就太好了。另外,我希望有一个不使用或很少使用 CSS hack 和/或非语义标记的解决方案。

【问题讨论】:

那篇文章中的方法在 Safari (4.0.5) 中崩溃了:S @ripper234 不完全是,因为这个问题是关于可变高度 div 另外,这个问题是先问的。 How to vertically center a div for all browsers?的可能重复 【参考方案1】:

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

为了更好地解释这项技术,您可以查看the article I adapted it from,但基本上它涉及添加一个额外的元素并在支持position:table\table-cell 的非表格元素的 IE 和浏览器中应用不同的样式。

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

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

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

更新:我们开始为 CSS3 获得更好的浏览器支持,将 flex-box 和变换作为获得垂直居中(以及其他效果)的替代方法。有关现代方法的更多信息,请参阅 this other question,但请记住,浏览器对 CSS3 的支持仍然很粗略。

【讨论】:

是的,我今天发现了那篇文章,但无法使它适用于我的特殊情况。也许我需要进一步研究。 也许您可以发布您正在使用但不起作用的代码? 这仍然是这个问题的最佳解决方案吗? 那篇文章似乎不适用于 Chrome 23、Firefox 16 和 IE 9。This answer 似乎是一个更好的解决方案。 不,截至 2013 年 2 月 24 日,该文章在最新的 Chrome 和 Firefox 中仍然有效【参考方案2】:

这似乎是我为这个问题找到的最佳解决方案,只要您的浏览器支持::before 伪元素:CSS-Tricks: Centering in the 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>

【讨论】:

现在 - 这是一个 -BRILLIANT- 解决方案。非常感谢您发布这个! 与其他答案一样,如果它描述了方法并包含链接中的代码,这会更好。 +1,这个解决方案真的很巧妙!顺便说一句,您可以添加 .block white-space: nowrap; font-size: 0; line-height: 0; 并在伪元素上保留负右边距,您只需在 .centered 上重置 fs 和 lh ......这样您可以确保即使元素比视口更宽,它也能正确定位(并且不必使用 imo 有点凌乱的负边距)。 @jessegavin - 在您看来……以下内容与您概述的方法有何不同:***.com/questions/396145/… 此外,当外部容器 .block 具有最小高度而不是高度时,这会发生故障。【参考方案3】:

使用子选择器,我采用了上面的Fadi's incredible answer 并将其归结为一个我可以应用的 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 谢谢。是的,它的性能可能会更差,但现在 CSS 规则可能不会对事情产生太大影响。我们可以通过选择&gt; div 来改进这一点。 calendar.perfplanet.com/2011/… 简单而伟大。非常适合我。【参考方案4】:

对于具有动态(百分比)高度的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>  

Try this by yourself.

【讨论】:

【参考方案5】:

只需添加

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

到内部 div。

它所做的是将内部 div 的顶部边框移动到外部 div 的一半高度 (top: 50%;),然后将内部 div 向上移动一半高度 (transform: translateY(-50%))。这将适用于 position: absoluterelative

请记住,transformtranslate 具有供应商前缀,为简单起见未包括在内。

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

【讨论】:

只是想知道为什么这适用于 Chrome 和 Firefox,但不适用于 Safari。然后我注意到大多数与transform 相关的东西都是以-webkit- 为前缀的,现在它可以工作了。所以提醒一下:不要忘记添加 -webkit- 前缀。 使用github.com/postcss/autoprefixer 之类的工具为您处理前缀。 这个答案应该在顶部。 这应该有更多的赞成票!顺便说一句,它也适用于position: absolute,不是吗? 这种方法在 Chrome 中有一个不幸的副作用——如果你的包装器有奇数个像素,那么translate 会在试图处理所有东西的 .5px 高度时模糊地渲染所有东西。【参考方案6】:

您可以使用自动边距。使用 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 实际上仍然是一个实验性功能;还没有浏览器正确支持它 2016年对display:flex的支持已经不错了。【参考方案7】:

目前为止对我来说最好的结果:

要居中的div:

position: absolute;
top: 50%;
transform: translateY(-50%);
margin: 0 auto;
right: 0;
left: 0;

【讨论】:

工作就像一个魅力【参考方案8】:

对我来说最好的方法是:

.container
  position: relative;


.element
  position: absolute;
  top: 50%;
  transform: translateY(-50%);

优点是不必明确高度

【讨论】:

【参考方案9】:

你可以使用弹性显示,例如下面的代码:

.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>

【讨论】:

以上是关于如何在div中以可变高度垂直居中内容?的主要内容,如果未能解决你的问题,请参考以下文章

如何在固定高度的div内垂直居中动态高度的图像?

如何在div中垂直居中图像

实现div内容水平垂直居中

div盒子水平垂直居中的方法

div盒子水平垂直居中的方法

如何让div中的内容垂直居中