如何在动态高度的 div 中垂直居中文本?

42
<body>
    <div style="position:absolute; height:100%; width:100%;">
        <h1 style="text-align:center;">Text</h1>
    </div>
</body>

我如何在div标签内垂直居中h1标签,无论div元素的高度如何? 也就是说,如果用户更改浏览器高度,我希望h1根据新高度在中心垂直对齐。

谢谢。


这是一篇关于该主题的优秀文章:http://phrogz.net/css/vertical-align/index.html - Surreal Dreams
10个回答

70

我遇到的最好的解决方案是利用 display 属性,将包装元素设置为 table ,以允许在要居中的元素上使用 vertical-align:middle

查看这个 工作示例

HTML

<body>
    <div>
        <h1>Text</h1>
    </div>
</body>

CSS

body {width: 100%; height: 100%;}   /* this is just to "view" the div height...*/

div {
    position:absolute; height:100%; width:100%;
    display: table;
}
h1 {
    display: table-cell;
    vertical-align: middle;
    text-align:center;
}

测试通过的系统

Windows XP Professional 版本 2002 Service Pack 3

  • Internet Explorer 8.0.6001.18702
  • Opera 11.62
  • Firefox 3.6.16
  • Safari 5.1.2
  • Google Chrome 18.0.1025.168 m

Windows 7 Home Edition Service Pack 1

  • Internet Explorer 9.0.8112.164211C
  • Opera 11.62
  • Firefox 12.0
  • Safari 5.1.4
  • Google Chrome 18.0.1025.168 m

Linux Ubuntu 12.04

  • Firefox 12.0
  • Chromium 18.0.1025.151 (开发版 130497 Linux)

1
这在IE7及以下版本中无法工作。但如果这不是一个问题 - 这是最好的解决方案。+1 - Zoltan Toth
这是一台离线的展示机,所以该应用只能在Firefox浏览器中运行。这个解决方案在我的情况下非常有效。+1 - Albion
1
我认为这是一个很好的解决方案,适用于动态高度和静态高度容器,运行良好。 - Sanjeev
1
请查看IE10+的更好答案:https://dev59.com/6Wgu5IYBdhLWcg3w9ryX#60909392 - Elijah Mock

19
我发现最不显眼且最不容易混淆的答案是在 <h1> 元素之前插入一个 <span> 标签:http://jsfiddle.net/Wexcode/axRxE/

HTML:

<div>
    <span></span><h1>Text</h1>
</div>​

CSS:

div { text-align: center; /* horizontally center */ }
div span {
    height: 100%;
    vertical-align: middle;
    display: inline-block; }
div h1 {
    vertical-align: middle;
    display: inline-block; }​

将此技术扩展为垂直对齐到浏览器高度:http://jsfiddle.net/Wexcode/axRxE/1/


谢谢你提供这个好的解决方法!我在这里为不支持的浏览器编写了一个备用方案(http://jsfiddle.net/axRxE/2/)。 - doptrois
你在<span><h1>标签之间添加的空格会影响垂直对齐。 - Wex
1
我尝试了很多方法,但都不起作用。这个简直太棒了,谢谢! - Daniel Z.
1
这将更简单通过使用:before伪元素。http://jsfiddle.net/6kk8yyxk/1/ - hakatashi

7

我有三行最简单的CSS代码,将会让你大吃一惊,并且你会想到“为什么我一开始没想到这个”。在你想要垂直居中定位的元素上使用此代码,并在父容器上添加100%的高度。

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

该位置可以是相对、绝对或固定的。


7

在2012年,被接受的答案是正确/最佳选项。

向前跳8年,弹性盒子(flex boxes)现在已被每个主流浏览器(IE10+)支持:

display: flex;
align-items: center;
flex-direction: column;  /* To also center horizontally, change to `rows` or remove */

注意:如果您关心 IE10,需要包含前缀版本 -ms- ,请参考上面的链接。


1
是的,我也更喜欢使用flex而不是top: 50%transform: translateY(50%)或表格。 - Dani Amsalem

4

http://jsfiddle.net/xQBbQ/

<body>
    <div style="position:absolute; height:100%; width:100%;">
        <h1 style="text-align:center; height:20px; position:relative; top:50%; margin-top:-10px;">Text</h1>
    </div>
</body>

这将无法处理超过两行的长文本,请参见此模拟,使用<br/>来强制换行! - Zuul
@Zuul OP没有说明文本的长度。无论如何,想法是设置<h1>的高度,并给出一半高度的负边距。 - Zoltan Toth
只是指出一个“尚未到来”的问题!你继续是正确的,此外,这里有一个+1来证明它! - Zuul

2

使用CSS2 + CSS3,无需任何Javascript,有一种跨(桌面)浏览器解决方案来实现此功能。

适用于以下浏览器:

  • IE5+
  • Gecko的(Mozilla、Firefox、Netscape 7)
  • Opera 7+
  • Konqueror 3+
  • Webkit浏览器(Safari、Google Chrome)
  • 还有很多(未测试移动浏览器)

文档:CSS中的垂直居中 具有未知高度的明确解决方案:
http://www.jakpsatweb.cz/css/css-vertical-center-solution.html

干净的jsFiddle示例: http://jsfiddle.net/WYgsP/


HTML

<div class="outerBox">
    <div class="helper">
        <div class="boxWithUnknownHeight">
            any text<br>
            any height<br>
            any content, for example generated from DB<br>
            everything is vertically centered
        </div>
    </div>
</div>​

CSS

.outerBox {
    display: table;
    height: 400px;
    #position: relative; /* ie hack */
    overflow: hidden;
    border: 1px solid red;
}

.helper {
    #position: absolute; /* ie hack */
    #top: 50%; /* ie hack */
    display: table-cell;
    vertical-align: middle;
}

.boxWithUnknownHeight {
    #position: relative; /* ie hack */
    #top: -50%;
    border: 1px solid green
}​

即使我通过Firebug等方式添加文本和换行符,它也可以正常工作。
为了保持你的CSS不受无效的CSS Hack影响,我建议您使用条件注释并创建一个包含特定浏览器代码的单独CSS文件。

关于未知高度的垂直居中是如何工作的以及原因:详细描述


其他解决方案使用display: table和/或display: table-cell以及绝对定位,在此查看


1
我在任何情况下都使用表格。就我个人而言,当已有相应功能时,我不喜欢使用display: table或类似的东西。
<table style="width: 100%; height: 100%;">
    <tr>
        <td>
            <!-- Whatever you want vertically and horizontally centered -->
        </td>
    </tr>
</table>

使用同样的方法,您可以为自己的情况做类似的事情:

<div id="container-div" style="position: relative">
    <div id="random-content-that-changes-container-height-and-width" style="height: 600px; width: 400px;">
    <div style="position: absolute; top: 0; right: 0; left: 0; bottom: 0">
        <table style="width: 100%; height: 100%;">
            <tr>
                <td>
                    <!-- Whatever you want vertically and horizontally centered -->
                </td>
            </tr>
         </table>
     </div>
</div>

人们担心语义类别(https://www.impressivewebs.com/avoid-nonsemantic-classes/),而你正在使用表格元素进行布局? - Julix
不用管了,这显然是一条旧评论,但如果你还在看,请查看这个链接:https://dev59.com/K3VD5IYBdhLWcg3wHnwX#84986 - Julix
唯一在2022年仍然对我有效的答案! - patrick

1
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
<!--
body {
    background-color: #0c0c0c;
}
.object {
    background-color: #666666;
    height: 350px;
    width: 600px;
}
.verticalCenter {
    width:600px;
    height:350px;
    position:absolute;
    left:50%;
    top:50%;
    margin:-175px 0 0 -300px;
}
-->
</style>
</head>
<body>
    <div class="verticalCenter">
        <div class="object">cetnered</div>
    </div>
</body>
</html>

您必须在 .verticalCenter 类中设置高度和宽度,与要居中的对象(div、flash、图像、文本)相同。边距必须是这些高度和宽度的一半。

如果您动态更改该对象,则我认为没有解决方案。除非,也许可以使用 JavaScript。


1
这里有一个相当简单的解决方案。主要是基于设置 display:table-cell 并选择垂直居中对齐方式。
HTML:
<div id="vertical">
    <p>this text is vertically centered.  It's long enough to wrap, and should work for any size chunk of content.</p>
    <p>Heck, it even works with multiple items in the middle.</p>
</div>​​

CSS:

#vertical {
    display:table-cell;
    vertical-align:middle;
    height: 500px;
    width: 300px;
}​

JSFiddle: http://jsfiddle.net/6Re3E/1/

JSFiddle:http://jsfiddle.net/6Re3E/1/

没错,它不适用于IE6或7。我相信IE7存在一个简单的JS解决方案。人生苦短,不必为IE6而担忧。 - Surreal Dreams
这个网站展示了一个解决方案,采用我们两种方法的混合(你的需要使用一个被居中的容器而不是原始内容进行微调):http://www.boutell.com/newfaq/creating/centervertically.html。 - Surreal Dreams

-2
在我看来,div在这种情况下不是一个合适的选择。我的建议是使用table并在其td上应用vertical-align样式。

2
不要将非表格数据放入表格中。 - Surreal Dreams
3
表格在语义上只适用于表格数据,其他情况不合适。 - Zoltan Toth
这是设计跨浏览器更可靠的解决方案。 - Tooraj Jam
1
不行。对于页面结构来说,它更加恶劣。忘掉表格吧 :) - Zoltan Toth
今天的观点很好。我没有想到过。谢谢大家。 - Tooraj Jam

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