如何使用CSS使<div>在父元素中垂直居中?

156

我想制作一个小的用户名和密码输入框。

我想问一下,如何垂直对齐一个div?

我现在有的代码是:

<div id="Login" class="BlackStrip floatright">
   <div id="Username" class="floatleft">Username<br>Password</div>
   <div id="Form" class="floatleft">
   <form action="" method="post">
      <input type="text" border="0"><br>
      <input type="password" border="0">
   </form>
   </div>
</div>

如何将ID为"Username"和"Form"的div垂直居中对齐?我已经尝试过以下代码:

vertical-align: middle;

我在CSS中针对id为Login的div做了一些样式设置,但似乎没有生效。希望能得到帮助。


3
请看这个链接:https://dev59.com/eXRC5IYBdhLWcg3wJNmf(注:原文为英文,本翻译为中文。) - sagarpatidar
17个回答

282

在现代浏览器中最好的方法是使用Flexbox:

#Login {
    display: flex;
    align-items: center;
}

一些浏览器需要使用特定的厂商前缀。对于不支持弹性盒子(比如 IE 9 及更早版本)的老旧浏览器,您需要使用其中一个旧方法实现回退解决方案。

推荐阅读


13
为了水平居中,我也添加了 justify-content: center。 (虽然情境不完全相同。) - meshy
如果您希望父元素保持内联,还可以使用display: inline-flex - thutt
6
使用flex-direction: column可以将多个div叠放在彼此之上。 - Danny Sullivan
Flex是我见过的最糟糕的方法,Bootstrap带来了很多痛苦,我更愿意使用Javascript而不是它... - Bartando
1
你真的救了我的命。我的老板 CJ 说,如果我今天不能完成这个任务,我就会有大麻烦。还有 @meshy,你的工作非常出色,谢谢! - user5402026
显示剩余3条评论

112

这可以通过3行CSS完成,并且向后兼容(包括)IE9:

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

示例: http://jsfiddle.net/cas07zq8/

来源


太棒了,只用了三行代码就完美运行了。 - Amit Kumar
这是我个人最喜欢的,特别是当我可以将它用作LESS或SASS混合时。 - AuRise
7
打破响应式设计 - Harry Bosh
2
你能提供一个例子来说明为什么它会破坏整个“响应式设计”吗?在我看来,它是否破坏了响应式设计取决于你的项目结构。 - Adam Copley
2
哇哦..谢谢,我不得不从滑块中删除flexbox,因为它在flex父元素和子元素之间插入了额外的div,这是完美的解决方案。 - Nishant
当你不知道高度时怎么办? - Gabriel

83

你可以在另一个

中垂直对齐
。请参见JSFiddle上的此示例,或考虑下面的示例。

HTML

<div class="outerDiv">
    <div class="innerDiv"> My Vertical Div </div>
</div>

CSS

.outerDiv {
    display: inline-flex;  // <-- This is responsible for vertical alignment
    height: 400px;
    background-color: red;
    color: white;
}

.innerDiv {
    margin: auto 5px;   // <-- This is responsible for vertical alignment
    background-color: green;   
}

.innerDiv 的边距必须使用这个格式:margin: auto *px;

[其中,* 是您想要的值。]

display: inline-flex 在支持HTML5的最新(更新/当前版本)浏览器中得到支持。

它可能在Internet Explorer中无法正常工作 :P :)

始终尝试为任何垂直对齐的

(即innerDiv)定义一个高度,以解决兼容性问题。


我对CSS不是很擅长,但在众多的解决方案中,这个对我来说是最好的。 - Sambhav Sharma
3
这在IE浏览器中无法运行。 - Steve Breese
display:flex 可以完成任务而不会破坏其他东西。 - atilkan
24
@SteveBreese 停止使用 IE。 http://breakupwithie8.com/ - atilkan
2
不兼容IE9。 - serge
1
只有在添加了负责垂直对齐的部分以及外部div的高度时,此解决方案才有效。如果没有高度,它将无法正常工作。 - davidneedham

14

虽然我来晚了,但这个垂直对齐的快速技巧是我自己想出来的,而且是我最喜欢的之一。它非常简单,并且很容易理解。

你可以使用 :before CSS 属性将一个 div 插入到父 div 的开头,给它设置 display:inline-blockvertical-align:middle,并将这些属性赋予子 div。由于 vertical-align 是用于在行上对齐,这些内联 div 将被视为一行。

:before div 的 height:100%,子 div 将自动跟随并垂直居中对齐在一个非常高的“线”上。

.parent:before, .child {
    display:inline-block;
    vertical-align:middle;
}
.parent:before {
    content:""; // so that it shows up
    height:100%; // so it takes up the full height
}

这里有一个代码片段可以演示我所说的。子div可以是任何高度,而您不必修改其边距/填充。
如果您不喜欢使用:before,您也可以手动放置一个div。

这里是一个更具解释性的代码片段.

<div class="parent">
    <div class="before"></div>
    <div class="child">
        content
    </div>
</div>

然后只需重新将.parent:before分配给.parent .before


1
太棒了!我第一次看到它,真的很惊讶为什么这么完美。我已经修改了CSS选择器为.parent > *,所以我不再需要子选择器了。这意味着我可以在任何地方使用这个类!我会点赞+1000。 - Salketer
太棒了!但是,为什么我们需要在子div垂直对齐之前插入一个div呢?(我发现这样不起作用,但为什么?) - Sasha Chirico
我能够使用这种技术在示例中的“child” div内包含一个次级子div。我的CSS文件中的媒体规则使我可以在宽屏幕上将新的子-子内容显示在原始内容的右侧,在窄屏幕上则显示在其下方并缩小,而且所有内容仍然垂直居中。换句话说,这对于我来说不仅适用于“child” div中的一些文本。 - David Rector

11

如果你知道高度,你可以使用带有负 margin-top 的绝对定位,就像这样:

#Login {
    width:400px;
    height:400px;
    position:absolute;
    top:50%;
    left:50%;
    margin-left:-200px; /* width / -2 */
    margin-top:-200px; /* height / -2 */
}

否则,只使用CSS无法真正实现垂直居中
的方式。

7
在我的Firefox和Chrome中,它们的表现为:
CSS:
display: flex;
justify-content: center;     // vertical align
align-items: center;         // horizontal align

3

@GáborNagy在另一篇文章中的评论是我能找到的最简单的解决方案,对我非常有效。由于他提供了一个jsfiddle,我在这里复制它并做了一些小改动:

CSS:

#wrapper {
    display: table;
    height: 150px;
    width: 800px;
    border: 1px solid red;
}

#cell {
    display: table-cell;
    vertical-align: middle;
}

HTML:

<div id="wrapper">
    <div id="cell">
        <div class="content">
            Content goes here
        </div>
    </div>
</div>

如果您还希望将其水平对齐,您需要在“cell” div内添加另一个div“inner-cell”,并为其添加以下样式:
#inner-cell{
      width: 250px;
      display: block;
      margin: 0 auto;
}

3

1
我需要指定最小高度。
#login
    display: flex
    align-items: center
    justify-content: center
    min-height: 16em

1

垂直对齐一直很棘手。

在这里,我介绍了一些垂直对齐div的方法。

http://jsfiddle.net/3puHE/

HTML:

<div style="display:flex;">

<div class="container table">
<div class="tableCell">
<div class="content"><em>Table</em> method</div>
</div>
</div>

<div class="container flex">
<div class="content new"><em>Flex</em> method<br></div>
</div>

<div class="container relative">
<div class="content"><em>Position</em> method</div>
</div>

<div class="container margin">
<div class="content"><em>Margin</em> method</div>
</div>

</div>

CSS:
em{font-style: normal;font-weight: bold;}
.container {
    width:200px;height:200px;background:#ccc;
    margin: 5px; text-align: center;
}
.content{
    width:100px; height: 100px;background:#37a;margin:auto;color: #fff;
}
.table{display: table;}
.table > div{display: table-cell;height: 100%;width: 100%;vertical-align: middle;}
.flex{display: flex;}
.relative{position: relative;}
.relative > div {position: absolute;top: 0;left: 0;right: 0;bottom: 0;}
.margin > div {position:relative; margin-top: 50%;top: -50px;}

1
工作中的jsFiddle https://jsfiddle.net/breese/3puHE/10/ - Steve Breese
为什么我的链接上面不起作用? - Barun
所有的框(HTML、JavaScript、CSS)都是空的。 - Steve Breese

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