使用margin:auto垂直对齐div


113

所以我知道如果使用,我们可以将div水平居中margin:0 auto;。应该按照margin:auto auto;我认为的方式工作?垂直居中吗?

为什么也vertical-align:middle;不起作用?

.black {
    position:absolute;
    top:0;
    bottom:0;
    left:0;
    right:0;
    background:rgba(0,0,0,.5);
}
.message {
    background:yellow;
    width:200px;
    margin:auto auto;
    padding:10px;
}
<div class="black">
    <div class="message">
        This is a popup message.
    </div>
</div>

JSFiddle


1
强烈建议阅读并实施以下有关Flexbox的@zpr答案。到今天为止,它得到了很好的支持,您的CSS将会干净得多。
Govind Rai

if((新Date())。getFullYear()> 2017)useFlexBox = true;
布兰迪托

Answers:


173

2020年8月更新

尽管下面的内容对于有用的信息仍然值得一读,但是Flexbox已有一段时间了,因此请按照此答案使用它。


您不能使用:

vertical-align:middle因为它是不是适用于块级元素

margin-top:auto并且margin-bottom:auto因为它们的使用值将计算为零

margin-top:-50%因为基于百分比的边距值是相对于包含块的宽度来计算的

实际上,文档流和元素高度计算算法的性质使得不可能使用边距将元素垂直放置在其父元素内部居中。每当垂直边距的值更改时,都会触发父元素高度的重新计算(重新流),这反过来又会触发原始元素的重新居中...使其成为无限循环。

您可以使用:

像这样的一些解决方法适用于您的情况;这三个元素必须像这样嵌套:

.container {
    display: table;
    height: 100%;
    position: absolute;
    overflow: hidden;
    width: 100%;
}
.helper {
    #position: absolute;
    #top: 50%;
    display: table-cell;
    vertical-align: middle;
}
.content {
    #position: relative;
    #top: -50%;
    margin: 0 auto;
    width: 200px;
    border: 1px solid orange;
}
<div class="container">
    <div class="helper">
        <div class="content">
            <p>stuff</p>
        </div>
    </div>
</div

根据Browsershot,JSFiddle可以正常工作。


10
#将规则的前缀仅由IE7及以下版本解释是一种黑客。你可能更喜欢,而不是包括在IE特定的样式表规则使用条件注释
OV

2
出于这种原因的理由+1,基于宽度的保证金百分比计算非常令人惊讶。
ricosrealm

2
我对“无限循环”陈述感到怀疑。
Barun 2014年

105
人类早在几年前就已经登上月球,我们仍然必须应对这种废话。在浏览器中垂直对齐的东西,耶稣
user151496 2015年

3
在> = IE9时代,position: absolute; top: 50%; transform: translateY(-50%);它也是可行的并且非常受欢迎...(除非top:50%;margin: - $halfHeight您不必事先知道身高...)
Frank Nocke

112

自2012年提出这个问题以来,浏览器对flexbox的支持已经走了很长一段路,我觉得这个回答似乎是必须的。

如果父容器的显示是flex,则margin: auto auto(也称为margin: auto)将工作水平和垂直居中两个,如果不考虑它是一个inlineblock元件。

#parent {
    width: 50vw;
    height: 50vh;
    background-color: gray;
    display: flex;
}
#child {
    margin: auto auto;
}
<div id="parent">
    <div id="child">hello world</div>
</div>

请注意,不必绝对指定宽度/高度,例如在本示例jfiddle中,它使用相对于视口的大小。

尽管在发布时,浏览器对flexbox的支持达到了空前的高,但是许多浏览器仍然不支持它,或者需要供应商前缀。有关更新的浏览器支持信息,请参阅http://caniuse.com/flexbox

更新资料

由于这个答案引起了大家的关注,因此我也想指出,您根本不需要指定margin是否要使用它display: flex,而是想将容器中的所有元素居中:

#parent {
    width: 50vw;
    height: 50vh;
    background-color: gray;
    display: flex;
    align-items: center; /* horizontal */
    justify-content: center; /* vertical */
}
<div id="parent">
    <div>hello world</div>
</div>


4
父{显示:flex; }子{保证金:自动0;}简直很棒。
Arek Kostrzeba '16

天哪,你是摇滚明星,该死,我不能多次投票支持你!
PirateApp '17

当您也可能对适合内容的问题感到困惑时,这是一个很好的答案。通过在容器上设置flex,内容div不需要设置任何属性。
埃里克

1
到目前为止,这是迄今为止在2018年工作的最佳,优雅的解决方案,谢谢。
SilverSurfer

我想补充一点,从2018年5月开始,使用此解决方案,文本不会在IE 11中垂直对齐
。– Yefu,

62

这是我找到的最佳解决方案:http : //jsfiddle.net/yWnZ2/446/可在Chrome,Firefox,Safari,IE8-11和Edge中使用。

如果你有一个声明heightheight: 1emheight: 50%,等),或者是在浏览器知道高度的元素(imgsvg,或canvas例如),那么所有你需要的垂直居中是这样的:

.message {
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
    margin: auto;
}

您通常需要指定一个width或,max-width这样内容就不会延伸到屏幕/容器的整个长度。

如果您要将此模式用于始终要在视口中与其他内容重叠的中心,请同时使用position: fixed;这两个元素而不是position: absolutehttp://jsfiddle.net/yWnZ2/445/

这是更完整的文章:http : //codepen.io/shshaw/pen/gEiDt


3
这并不一定使它在其父元素中居中。不错,如果您只想将其放在页面中心,就可以了。
乔尔·梅隆

2
只需添加position: relative到父项,该元素将在父项中居中。我做了关于该技术的碎杂志更大的书面记录,如果你想了解更多:coding.smashingmagazine.com/2013/08/09/...
shshaw

有时候,绝对是基于一个或两个以上的父母(相对于身体)而相对的则可能是祖父母或曾祖父母(相对于父母)。也许那些知道何时或为什么发生这种情况的人可以更好地控制此技术-我从未真正研究过这些问题,但我确实知道从绝对切换为相对并不是从本质上解决此问题的解决方案。我读了一些您的文章,看起来绝对绝对和相对绝对上升到第一个绝对绝对或相对祖先,对吗?
乔尔·梅隆

我有点儿慢。我只是在上面重新阅读了您的评论。我没有注意到您说过将其添加到parent-知道了。非常感谢!
乔尔·梅隆

1
@commonpike IE8 / 9的唯一问题是是否display: table用于可变高度内容。否则,此方法应按预期工作。通读书面记录的整体更多的细节。您还应该能够测试完整视图在IE8 / 9中,以查看是否存在任何问题。
shshaw

21

编辑:这是2020年,我会改用弹性盒。

原始答案:

HTML

<body>
  <div class="centered">
  </div>
</body>

的CSS

.centered {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

不适用于IE 8和旧版本的ie。从9.0版开始,支持转换属性(带有-ms-前缀)。(即10不再需要前缀)。
DevWL

5
没错,我不在乎IE8
Gal Margalit 2015年

而作家标记HTML5的提问☺
加尔利特

9

我知道问题出在2012年,但我找到了有史以来最简单的方法,我想分享一下。

HTML:

<div id="parent">
     <div id="child">Content here</div>
</div>

和CSS:

#parent{
     height: 100%;
     display: table;
}    
#child {
     display: table-cell;
     vertical-align: middle; 
}

7

如果知道要居中的div的高度,则可以将其绝对定位在其父级内,然后设置top值为50%。这样会使子div的顶部向下倾斜50%,即过低。通过设置其将其拉回margin-top为高度的一半。因此,现在您将孩子div的垂直中点置于父级的垂直中点-垂直居中!

例:

.black {
    position:absolute;
    top:0;
    bottom:0;
    left:0;
    right:0;
    background:rgba(0,0,0,.5);
}
.message {
    background:yellow;
    width:200px;
    margin:auto auto;
    padding:10px;
    position: absolute;
    top: 50%;
    margin-top: -25px;
    height: 50px;
}
<div class="black">
    <div class="message">
        This is a popup message.
    </div>
</div>

http://jsfiddle.net/yWnZ2/2/


1
margin-top不能以相对于元素高度的%设置,因此您将获得尺寸依赖的修正
ov 2012年

1
正是我在回答中所说的?“如果知道div的高度,则要居中”。我没有说OP应该在中使用%margin-top
凝灰岩2012年

我不同意该解决方案,因为它会将您锁定在预定义的元素高度中-但是您的评论是有意义的。您可能需要在答案中反映出来
ov 2012年

3
好的,我已经将您忽略的部分加粗了,希望现在已经清楚了。
tuff 2012年

1
@ov:如果元素没有固定的高度,则可以使用JS来获取计算出的高度,然后相应地设置负的上边距。我认为,这仍然是垂直居中的最佳方法。
daGUY 2012年

3

这两个解决方案仅需要两个嵌套元素。
首先 -相对和绝对定位(如果内容为静态)(手动居中)。

.black {
    position:relative;
    min-height:500px;
    background:rgba(0,0,0,.5);

}
.message {
    position:absolute;
    margin: 0 auto;
    width: 180px;
    top: 45%; bottom:45%;  left: 0%; right: 0%;
}

https://jsfiddle.net/GlupiJas/5mv3j171/

用于流畅的设计 -对于确切的资源中心,请使用以下示例:

.message {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

https://jsfiddle.net/GlupiJas/w3jnjuv0/

如果内容超过窗口高度的50%,则需要设置“最小高度”。您还可以通过移动设备和平板电脑设备的媒体查询来控制此高度。但前提是您要使用响应式设计。

我想您可能会更进一步,如果出于某种原因需要使用简单的JavaScript / JQuery脚本来控制最小高度或固定高度。

第二 - 如果内容是流畅的,您还可以使用具有垂直对齐方式和文本对齐居中的table和table-cell的CSS属性:

/*in a wrapper*/  
display:table;   

/*in the element inside the wrapper*/
display:table-cell;
vertical-align: middle;
text-align: center;

完美地工作和缩放,通常用作响应式Web设计解决方案,具有可控制对象宽度的网格布局和媒体查询。

.black {
    display:table;
    height:500px;
    width:100%;
    background:rgba(0,0,0,.5);

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

https://jsfiddle.net/GlupiJas/4daf2v36/

我更喜欢使用表格解决方案来实现精确的内容居中,但是在某些情况下,相对绝对定位会做得更好,特别是如果我们不想保持内容对齐的确切比例。


2

.black {
    display:flex;
    flex-direction: column;
    height: 200px;
    background:grey
}
.message {
    background:yellow;
    width:200px;
    padding:10px;
    margin: auto auto;
}
<div class="black">
    <div class="message">
        This is a popup message.
    </div>
</div>


您能和我们分享一下,这个解决方案如何?另外,我在底部看到您的“弹出消息”没有居中
Alex

我确实错过了一些事情,但是现在可以使div垂直保持在中间。您现在可以检查。
Seetpal singh

0

没有一种简单的方法可以使div垂直居中,这种方法可以在每种情况下都能解决问题。

但是,根据情况,有很多方法可以做到这一点。

以下是其中一些:

  • 设置父元素的顶部和底部填充,例如padding:20px 0px 20px 0px
  • 使用表格,表格单元格垂直放置其内容
  • 设置父元素的相对位置和要垂直居中的div的绝对位置,并将其设置为top:50px; 底部:50px;例如

您也可以在Google上搜索“ css垂直居中”


0

可变高度,上下边距自动

.black {background:rgba(0,0,0,.5);
width: 300px;
height: 100px;
display: -webkit-flex; /* Safari */
display: flex;}
.message{
background:tomato;
margin:auto;
padding:5%;
width:auto;
}
<div class="black">
<div class="message">
    This is a popup message.
</div>

可变高度,上下边距自动


0

使用Flexbox:

HTML:

<div class="container">
  <img src="http://lorempixel.com/400/200" />
</div>

CSS:

.container {
  height: 500px;
  display: flex;
  justify-content: center; /* horizontal center */
  align-items: center;     /* vertical center */
}

查看结果


0
.black {
    position:absolute;
    top:0;
    bottom:0;
    left:0;
    right:0;
    background:rgba(0,0,0,.5);
}
.message {
    position: absolute;
    top:50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background:yellow;
    width:200px;
    padding:10px;
}

 - 


----------


<div class="black">
<div class="message">
    This is a popup message.
</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.