使一个div在视口中水平垂直居中

43

我有一个包含整个网站内容的

容器。我试图使用CSS属性如margin:0 auto; on #wrapper来使该div垂直和水平居中。

#wrapper
{
 width:500px;
 height:500px;
 margin:0 auto;
 background:#f7f7f7;
}

使用上述CSS可以将div置于屏幕顶部中心,但如何使它在垂直方向上居中。当我在Firefox缩小页面时,div会在顶部中心处缩小,但我想让它始终从垂直和水平两个方向上居中。

有没有人可以建议一下如何实现这样的布局。

提前感谢。


你可以查看这个链接 https://dev59.com/xHRB5IYBdhLWcg3wUVxd#42204490 - vikas etagi
6个回答

59
#wrapper
{
 width:500px;
 height:500px;
 margin:0 auto;
 background:#f7f7f7;
 position:absolute;
 left:50%;
 top:50%;
 margin-left:-250px;
 margin-top:-250px;
}

演示: http://jsfiddle.net/fJtNQ/

为什么这个代码可行?

基本上,你在dom中有一个绝对定位的元素。这意味着你可以将它放置在任何你想要的位置,如果你没有相对定位的父元素,那么左边和顶部就是相对于文档的左上角。

给该元素分配 left:50%top:50% 可以使该元素始终处于屏幕中央,但实际上该元素的中心点在左上角。

如果你拥有固定的宽度/高度,你可以通过给负的 margin-leftmargin-top 赋值(因此借助一些非常简单的基本数学知识,它们的值将是 -(width/2)-(height/2)),从而轻松“转换”元素中心点为包装器div的中心点。

编辑

你还可以通过使用 flexbox 轻松居中,而且(很重要)不需要指定宽高,例如:

body { /* can also be whatever container */
  display: -webkit-flex;
  display: flex;
  -webkit-align-items: center;
  align-items: center;
  -webkit-justify-content: center;
  justify-content: center;
}

#wrapper {
  /* whatever style u want */
}

示例:https://jsfiddle.net/00utf52o/


1
过去,我使用的方法是将包装器放入另一个容器元素中。将外部垂直居中,内部水平居中。这样做更好。 - Dan Hanly
你说得对,我当时在用手机,因为解决方案非常简单,所以我只用了一秒钟就回答了。我会尽快解释的 :) - stecb
@stecb 记住,他接受了并不意味着你不需要解释发生了什么。至少放一个链接到一个垂直对齐的教程中去。有参考资料是很好的。 ;) - ShadowScripter
@dreamster 是的,你可以使用flexbox,这很简单:http://jsfiddle.net/6wb420m0/2/ - stecb
@dreamster 啊,我明白你的意思了。也试试一个 fiddle 吧 ;) - stecb
显示剩余5条评论

40

@stecb的回答在处理固定宽度/高度时很好用。

要在所有视窗中垂直居中定位一个div或图像并使其具有响应性,请使用以下代码:

#elem-to-center {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

我刚刚用 transform 替换了 margin-left 和 margin-top。

如果你想要一个包围元素的 margin,使用这个:

#outer-elem {
    width: 100%;
    height: 100%;
    padding: 30px;
    background: #fafafa;
    position: relative;
}
#elem-to-center {
    width: calc(100% - 60px);
    max-height: calc(100% - 60px);

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

JSFiddle | 源代码

我发现即使在响应式视图中,这也很有用。


#elem-to-center 在大视口下运作良好。但是在小视口下会出现问题。如何将此解决方案转换为小视口? - Gitau Harrison
@GitauHarrison 我刚刚检查了JSFiddle,但无法重现。也许你的样式不同。你能否简要解释一下你想要实现什么?提供一个fiddle会更有帮助。 - musafar006

17

对于需要将子div相对于视口而非父div居中的人,以下是一个解决方案。其他在此处提到的解决方案在这种情况下不起作用,因为它们倾向于使子div相对于父div居中。

<div id="container">
  <div id="wrapper">Always center, No matter the parent div's position</div>
</div>

#wrapper {
 width:300px;
 height:300px;
 margin:0 auto;
 background:green;
 position:fixed;
 left:50%;
 top:50%;
 margin-left:-150px;
 margin-top:-150px;
}

#container {
  display: block;
  position: absolute;
  width: 400px;
  height: 400px;
  border: 1px solid red;
  bottom: 0;
  left: 0;
}

演示在这里http://jsbin.com/yeboleli/2/edit?css,output


当我打开你的演示时,wrapper 元素在水平方向上居中,但在垂直方向上并没有居中。 - Krisztián Balla
固定定位是正确的方法,其他解决方案并不像你提到的那样有效,因为它们没有根据视口来实现。 - undefined

2
我使用jQuery。
$(window).resize(function(){

    $('.className').css({
        position:'absolute',
        left: ($(window).width() - $('.className').outerWidth())/2,
        top: ($(window).height() - $('.className').outerHeight())/2
    });

});

// To initially run the function:
$(window).resize();

5
在可以仅使用 CSS 解决问题的情况下,应始终避免使用 JavaScript。 - stecb
1
@stecb 不仅应该避免这种情况,而且它会让你看起来不够酷。CSS一直是时尚的代名词。 - ShadowScripter
1
因此,应该简化“你”的词语。使用 CSS 处理那些可能是动态的、无法通过 CSS 解决的事情应该被避免。当然,我也可以居中一个正方形……但如果那个正方形变成了其他形状呢…… - Hupperware
这是另一个问题 :P...这是一个针对具有固定宽高元素的通用解决方案。如果不同情况无法通过CSS解决,我更喜欢更改布局而不是选择JS(在我看来,JS不应该用于解决布局问题)。 - stecb
2
CSS解决方案需要您知道元素的宽度和高度。在响应式布局中,元素的宽度和高度会发生变化。 - Tony Topper
2
补充一下,如果您想要将Elm垂直居中到视口,而不管滚动位置如何,您需要考虑它们当前的垂直滚动位置,并将其添加到顶部值。top: $('.elm').css('top', ($(window).height() - $(elm).outerHeight())/2 + $(window).scrollTop()) - Jose Browne

1

最简单、最干净的方法是使用视口大小设置高度、边距(如果需要,还可以设置宽度)。
例如,你想让容器的height占据屏幕的60%(60vh),你可以将其余的空间(因为视口的总高度=100vh)平均分配给上下边距,这样元素就会自动居中对齐。
margin-leftmargin-right设置为auto,可以确保容器在水平方向上居中对齐。

.container {
         width: 60vw; /*optional*/
         height: 60vh;
         margin: 20vh auto;
         background: #333;
 }
<div class="container">
</div>


0

考虑在一个单独的元素上使用 "display: table" 和 "display: table-cell; vertical-align: middle"。因为 CSS 没有语义含义,所以这是一个可接受的解决方案。
我已经为你准备了一个例子:http://dabblet.com/gist/2002681 唯一的缺点是它需要比其他一些解决方案更多的标记,但它可以根据内容收缩和扩展。

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