在另一个 div 中垂直居中一个 div

653

我想让一个位于另一个div内部的div居中。

<div id="outerDiv">
    <div id="innerDiv">
    </div>
</div>

这是我目前正在使用的CSS。

    #outerDiv {
        width: 500px;
        height: 500px;
        position: relative;
    }
    
    #innerDiv {
        width: 284px;
        height: 290px;
        position: absolute;
        top: 50%;
        left: 50%;
        margin-top: -147px;
        margin-left: -144px;
    }

从你可以看到,我现在使用的方法取决于#innerDiv的宽度和高度。如果宽度/高度发生变化,我将不得不修改margin-topmargin-left的值。是否有通用的解决方案,可以使#innerDiv独立于其大小居中对齐?

我发现使用margin:auto可以将#innerDiv水平对齐到中间。那么垂直对齐呢?


如果您使用margin-top: auto; margin-bottom: auto;会发生什么? - Muhammad Umer
1
http://jsfiddle.net/k6ShD/4/ - Muhammad Umer
这里有两种简单的方法可以在div中心垂直、水平或同时居中(纯CSS):https://dev59.com/bmct5IYBdhLWcg3wmOZN#31977476 - Michael Benjamin
别人给的建议是正确的。只是补充一下。 如果你有一个名为DivParent的父级div和一个名为ChildDiv的子级div,那么 只需在子级div中添加margin: auto,这将使子级div或内部div居中于父级div。 - Alok Ranjan
24个回答

953

简洁版

竖直居中可以使用,但你需要在父元素上使用table-cell,并在子元素上使用inline-block

这个解决方案不适用于IE6和7。对于那些浏览器来说,你的方法更加安全。但是,考虑到你标记了CSS3和HTML5,我认为你不介意使用一种现代的解决方案。

经典解决方案(使用表格布局)

这是我的原始答案。它仍然有效,并且具有广泛的支持。表格布局会影响渲染性能,因此建议您使用更现代的解决方案之一。

这里是一个示例


测试环境:

  • FF3.5+
  • FF4+
  • Safari 5+
  • Chrome 11+
  • IE9+

HTML

<div class="cn"><div class="inner">your content</div></div>

CSS

.cn {
  display: table-cell;
  width: 500px;
  height: 500px;
  vertical-align: middle;
  text-align: center;
}

.inner {
  display: inline-block;
  width: 200px; height: 200px;
}

现代解决方案(转换)

由于变换功能现在得到了相当好的支持,因此有一种更简单的方法可以实现它。

CSS

.cn {
  position: relative;
  width: 500px;
  height: 500px;
}

.inner {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%,-50%);
  width: 200px;
  height: 200px;
}

演示


♥ 我最喜欢的现代解决方案(flexbox)

我开始越来越多地使用flexbox,它现在也得到了很好的支持,这是迄今为止最简单的方式。

CSS

.cn {
  display: flex;
  justify-content: center;
  align-items: center; 
}

演示

更多例子和可能性: 在一个页面上比较所有方法


272
虽然这样做可以起到作用,但它仅仅是一个很好的例子,说明了CSS的缺陷之处。像这样简单的东西不应该需要临时补救和绕过去的方法。 - Andrew S
7
在父元素中包含 display: table; 有多重要? - Timofey Drozhzhin
1
是的,你的例子是正确的。我在谈论你回答中的代码(这里)。你似乎有“position:flex”,这似乎不是一个有效的CSS属性。 - CpnCrunch
1
@CpnCrunch 不好意思,我把它改成了 display: flex。 - meo
5
这个答案解决了我折腾了三个小时仍无法让 div 垂直对齐的烦恼。那个 flex 的例子完美地解决了问题,因为客户使用的是 IE11/Chrome 浏览器,所以我可以毫无问题地使用它。非常感谢! - DangerousDetlef
显示剩余21条评论

130

实现水平和垂直居中的另一种方法是:

.Absolute-Center {
  margin: auto;
  position: absolute;
  top: 0; left: 0; bottom: 0; right: 0;
}

(参考资料)


1
+1,但它奇怪地取决于位置的顺序。从 bottom: 0; left: 0; 开始会使内部 div 粘在父元素的底部(无论是 Chrome 33 还是其他版本)。 - Patrick M
在您想要对齐div的方向中定义0,例如在我的情况下,在搜索表单字段中是这样的:.search-header{ margin:auto; top:0px; bottom:0px; right:0px; }没有分配'left'来继续前一个<div>的顺序和位置。 - UrielUVD
不需要精确说明父级div必须定位 - Matthieu Charbonnier
9
我认为这是更优秀的解决方案,但仅限于您的内部元素高度可以事先指定的情况下。这使其不适用于垂直居中流动文本等情况。 - Benji XVI
左对齐无效,始终靠左对齐(OS/X Chrome 66.0.3359.117) - lilalinux
这个代码是将内部div水平居中,而不是垂直居中。 - mLstudent33

52

另一种方法是使用Transform Translate

外部Div必须将其position设置为relativefixed,而内部Div必须将其position设置为absolute,并将topleft设置为50%以及应用transform: translate(-50%, -50%)

div.cn {
    position: relative;
    width: 200px;
    height: 200px;
    background: gray;
    text-align: center;
}

div.inner {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 100px;
    height: 100px;
    -webkit-transform: translate(-50%, -50%);  
    transform: translate(-50%, -50%);   
    background: red;
  
}
<div class="cn">
    <div class="inner">
        test
    </div>
</div>

测试环境:

  • Opera 24.0(最低版本要求 12.1)
  • Safari 5.1.7(最低版本要求带有-webkit-前缀的版本为4)
  • Firefox 31.0(最低版本要求带有-moz-前缀的版本为3.6,从16版本开始可以不加前缀)
  • Chrome 36(最低版本要求带有-webkit-前缀的版本为11,从36版本开始可以不加前缀)
  • IE 11, 10(最低版本要求带有-ms-前缀的版本为9,从10版本开始可以不加前缀)
  • 更多浏览器支持情况,请查看 Can I Use?

8
这段代码最好的地方是它与全宽的外部 div 完美搭配。做得很棒! - Nizam Kazi
我知道我们需要使用transform: translate(-50%, -50%);来真正居中div,但是为什么仅使用top:50%left:50%不起作用呢?有人可以更详细地解释一下吗? - Kevin Chandra
1
@KevinChandra,我认为topleft是指容器的尺寸,而translate则是指内容的大小。希望这可以帮到你! - rnrneverdies

51

只需三行CSS代码即可垂直对齐任何元素

HTML

<div class="parent-of-element">

    <div class="element">
        <p>Hello</p>
    </div>

</div>

最简单的

.element {
  position: relative;
  top: 50%;
  transform: translateY(-50%);
}

CSS

.parent-of-element {
   position: relative;
   height: 500px;
   /* or height: 73.61% */
   /* or height: 35vh */
   /* or height: ANY HEIGHT */
}

.element {
  position: absolute;
  top: 50%;

  -webkit-transform: translateY(-50%);
      -ms-transform: translateY(-50%);
          transform: translateY(-50%);
}

根据 shouldiprefix 的说法,这些是您所需的唯一前缀。
只要元素的父级具有高度或某些扩展其垂直尺寸的内容,您也可以使用%作为.parent-of-element的 'height' 属性的值。请确保涵盖元素拥有高度或某些内容以扩展其垂直尺寸。

1
我不能告诉你为什么,但在我的情况下,当我在translateY上使用(50%)而不是(-50%)时,它完美地工作了。 - jumps4fun
4
我喜欢这个方案的优雅性。唯一的问题是,如果用户将浏览器压缩到100px高(例如),我会失去居中<div>的顶部,这对我来说是有问题的,因为我希望我的标题在那里出于美学/设计原因。但老实说:我非常喜欢这个解决方案,我甚至不确定我是否在意这个问题! - Deborah Cole
1
KjetilNordin,根据您的布局,有时使用50%而不是-50%可以工作。但只要居中元素的容器具有高度,-50%就可以完美地工作。 - drjorgepolanco

22

我发现,与其把自己绑成一个不易编写和维护的CSS(还需要仔细地进行跨浏览器验证!),不如放弃CSS,使用非常简单的HTML 1.0:

<table id="outerDiv" cellpadding="0" cellspacing="0" border="0">
    <tr>
        <td valign="middle" id="innerDiv">
        </td>
    </tr>
</table>

这样做达到了原帖作者想要的一切,而且稳健且易于维护。


11
大多数人不认为这是一种好的做法,我也同意。像“table”这样的标记元素不应该用于布局。如果你要显示表格数据,才使用table标记。 - Milan Nankov
8
如果你对风格的重视高于可维护性的话,那么你的担忧是有道理的。其他人可能会有不同的权衡标准,他们应该看到所有的选择。 - Iron Pillow
3
我认为这个解决方案非常棒,绝对是跨浏览器的。 - Geomorillo
10
尽管CSS纳粹及其对表格的仇恨,我认为这种解决方案比堆积充满神秘感的CSS指令要好得多,而这些指令本质上仍然依赖于表格格式。就目前状态而言,CSS无法正确处理这个问题。 - kuroi neko
5
一票赞同意味着CSS正在积累大量的解决方法(至少在术语上)来实现这个简单的事情。对于开发人员来说,这绝对是一个更易管理的解决方案,但我希望未来不需要这样做。 - gkakas
显示剩余6条评论

14

您可以通过添加以下提到的CSS样式来实现。这得到了大多数浏览器的支持。您可以在此处检查浏览器支持情况。祝你好运。如有任何疑问,请留言。

#outerDiv {
        width: 500px;
        height: 500px;
        position:relative;
        background:grey;
        display:flex;
        justify-content:center;
        align-items:center;
    }

#innerDiv {
        background:cyan;
        width: 284px;
        height: 290px;
    }
<div id="outerDiv">
    <div id="innerDiv">
        Inner Div
    </div>
</div>


6
我个人更喜欢使用隐藏的伪元素技巧来覆盖整个外部容器的高度,并将其与其他内容垂直对齐。Chris Coyier在他的文章中对这个技术进行了很好的介绍。http://css-tricks.com/centering-in-the-unknown/ 这种方法的巨大优势是可伸缩性。您不需要知道内容的高度或担心它的增长/缩小。这种解决方案是可以扩展的 :)。
以下是CSS和一个工作示例的fiddle。 http://jsfiddle.net/m5sLze0d/
.center:before {
    content: ""; /* Adding Extra Space Above Element */
    display: inline-block;
    height: 100%;
    margin-right: -0.3em;
    vertical-align: middle;
}
.center_element {
    display:inline-block;
    float:none;
    vertical-align:middle;
    white-space:normal;
    text-align:left;
}

6年后,这是最好的解决方案! - BuffMcBigHuge

5
如果你在阅读以上精彩答案后仍然不理解,以下是两个简单的示例,展示如何实现它。

使用 display: table-cell

.wrapper {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
  width: 400px;
  height: 300px;
  border: 1px solid #555;
}

.container {
  display: inline-block;
  text-align: left;
  padding: 20px;
  border: 1px solid #cd0000;
}
<div class="wrapper">
  <div class="container">
    Center align a div using "<strong>display: table-cell</strong>"
  </div>
</div>

Using flex-box (display: flex)

.wrapper {
  display: flex;
  justify-content: center;
  width: 400px;
  height: 300px;
  border: 1px solid #555;
}

.container {
  align-self: center;
  padding: 20px;
  border: 1px solid #cd0000;
}
<div class="wrapper">
    <div class="container">
        Centering a div using "<strong>display: flex</strong>"
    </div>
</div>

注意:在使用上述实现之前,请检查 display: table-cell 和 flex 的浏览器兼容性。

4

在另一个 div 中垂直居中 div 项目

只需将容器设置为 display:table,然后将内部项目设置为 display:table-cell。在容器上设置一个 height,然后在内部项目上设置 vertical-align:middle。它具有广泛的兼容性,可以向后兼容到 IE9。

请注意,垂直对齐将取决于父容器的高度。

.cn
{
display:table;
height:80px;
background-color:#555;
}

.inner
{
display:table-cell;
vertical-align:middle;
color:#FFF;
padding-left:10px;
padding-right:10px;
}
<div class="cn">
  <div class="inner">Item 1</div>
  <div class="inner">Item 2</div>
</div>


3

当你的 height 没有设置(即为auto)时,你可以给内部 div 元素添加一些 padding(上下)来使其垂直居中:

<div>
    <div style="padding-top:20px;padding-bottom:20px">
    <!--content-->
    </div>
</div>

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