在 <DIV> 中垂直居中文本

51

我有一个高度固定的<div>元素,我想在其中垂直居中一些文本。

我一直在尝试按照这个网站上的说明:http://phrogz.net/css/vertical-align/index.html。但是,它似乎对我没有用。

我在http://jsfiddle.net/scwebgroup/74Rnq/上发布了我正在尝试的内容。如果我将HeaderBrand的margin-top改为大约-22px,则看起来就差不多了。

有人能看出为什么这篇文章描述的技术对我没有起作用吗?

注意:最佳答案在这里只适用于文本不换行到第二行的情况。


正确的演示:http://jsfiddle.net/74Rnq/2/ - Šime Vidas
谢谢,但在Google Chrome中,文本没有垂直居中。 - Jonathan Wood
那不应该是解决方案。我只是改进了你自己演示的展示方式。 - Šime Vidas
@JonathanWood 我选择那个答案是因为它更受欢迎。重复并不总是关于新旧之间的区别,例如,在 Meta 上的这个主题。 - user
7个回答

46
这是一个段落:
<!DOCTYPE html>
<style>
  .outer { outline: 1px solid #eee; }
  .outer > p { display: table-cell; height: 200px; vertical-align: middle; }
</style>

<div class="outer">
  <p>This text will be vertically aligned</p>
</div>

<div class="outer">
  <p>This longer text will be vertically aligned. Assumenda quinoa cupidatat messenger bag tofu. Commodo sustainable raw denim, lo-fi keytar brunch high life nisi labore 3 wolf moon readymade eiusmod viral. Exercitation velit ex, brooklyn farm-to-table in hoodie id aliquip. Keytar skateboard synth blog minim sed. Nisi do wes anderson seitan, banksy sartorial +1 cliche. Iphone scenester tumblr consequat keffiyeh you probably haven't heard of them, sartorial qui hoodie. Leggings labore cillum freegan put a bird on it tempor duis.</p>
</div>

能够在现代浏览器中工作,无论文本是单行还是多行。

同时,在http://jsfiddle.net/74Rnq/135/更新了代码片段。当元素本身只有150像素宽度时,不确定您为什么要在左侧添加625像素的边距...通过删除内联样式并使用一些填充来整理了一下布局。


14

您可以尝试将行高设置为该div的高度,如下所示:

<div style="height:200px;border:1px solid #000;"> 
    <span style="line-height:200px;">Hello world!</span> 
</div> 

这里有另一种似乎有效的技巧:

#vertical{
    position:absolute;
    top:50%;    
    left:0;
    width:100%;
}

<div style="position:relative;height:200px;">
    <div id="vertical">
        Hello world!
    </div>              
</div>

1
谢谢,但这似乎是我在结尾提到的stackoverflow链接中描述的相同技术。这是一种很好的清洁技术,但如果文本换行到第二行,则会失败。 - Jonathan Wood
1
@JonathanWood - 如果您想要使用多行文本的这种技术,您可以在这里查看我的答案:https://dev59.com/gWsz5IYBdhLWcg3w9syr#7542684 - Alohci
谢谢,但这对我来说有点太“超出范围”了。你警告它不适用于IE7,这对我来说是一个致命伤。 - Jonathan Wood

5
我知道这种方法会添加一些HTML,但是在所有主流浏览器(甚至IE7+)中都能正常工作。
基本的HTML结构。
<div id="hold">
  <div>Content</div>
  <div class="aligner">&nbsp;</div>
</div>​

需要 CSS

#hold{
    height:400px;
}
div{
    display:        -moz-inline-stack;
    display:        inline-block;
    zoom:            1;
    *display:        inline;
    vertical-align:middle;
}
.aligner{
    width:0px;
    height:100%;
    overflow:hidden;
}​

jsFiddle链接如下:


4

As shown below you can easily just set the parent of a text element to position: relative, and the text element itself to position: absolute; Then use direction properties to move around the text inside the parent. See examples below...

<!--Good and responsive ways to center text vertically inside block elements-->
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Centered Text&reg;</title>
<style type="text/css">
@charset "UTF-8";
* {
 margin: 0;
 padding: 0;
}

body {
 font-family: Helvetica;
}

#wrapper {
 width: 100%;
 height: auto;
}

#wrapper > div {
 margin: 40px auto;
 overflow: hidden;
   position: relative;
   height: 100px;
   width: 50%;
}

p {
 position: absolute;
 word-wrap: break-word;
 text-align: center;
 color: white;
 background-color: rgba(0,0,0,0.5);
}

#parent1 {
  background-color: orange;
}

#parent1 p {
   top: 10px;
   bottom: 10px;
   left: 10px;
   right: 10px;
   height: auto;
   width: auto;
   padding-top: 30px; /* Parent1's height * 0.5 = parent1 p's padding-top (Adjust to make look more centered) */
}

#parent2 {
 background-color: skyblue;

}

#parent2 p {
 left: 50%;
 top: 50%;
 padding: 10px;
 transform: translate(-50%, -50%);
}

#parent3 {
 background-color: hotpink;
}

#parent3 p {
 top: 50%;
 left: 0;
 transform: translateY(-50%);
 width: 100%;
}
</style>
</head>
<body>
<div id="wrapper">
 <div id="parent1">
  <p>Center Method 1</p>
 </div>
 <div id="parent2">
  <p>Center Method 2</p>
 </div>
 <div id="parent3">
  <p>Center Method 3</p>
 </div>
</div>
</body>
</html>

I hope this helps!


1
我最近很高兴地发现 Flexbox 可以为您解决这个问题。下面的 CSS 中的 flex-center 类将使您的 div 文本在垂直和水平方向上都居中对齐。示例可能会有些混乱,因此建议调整窗口大小,直到 div 边框与文本不对齐。

至于使用 flexbox 是否兼容性良好,请参见 Can I use...

我不完全理解为什么这个方法可行,如果有人对 flexbox 机制有更深入的了解,我会很享受解释。

.border-boxed {
  box-sizing: border-box;
}

*, *:before, *:after {
  box-sizing: inherit;
}

body {
  /* This is just to make it look pretty */
  box-sizing: border-box;
  background: linear-gradient(135deg, 
    rgba(85,239,203,1) 0%,
    rgba(30,87,153,1) 0%,
    rgba(85,239,203,1) 0%,
    rgba(91,202,255,1) 100%);
  color: #f7f7f7;
  font-family: 'Lato', sans-serif;
  font-weight: 300;
  font-size: .8rem;
  
  /* Expand <body> to entire viewport height */
  height: 100vh;
  
  /* Arrange the boxes in a centered, vertical column */
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

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


.box {
  width: 25%;
  height: 25%;
  border: 2px solid #f7f7f7;
  border-radius: 16px;
  margin: .5rem; 
  text-transform: uppercase;
  text-align: center;
}

.small {
  height: 8%; 
}
<div class="box large flexitem flex-center">
  Large Box. <br>
  So big. <br>
  My god.
</div>

<div class="box small flexitem flex-center">
  Smaller Box
</div>


1

使用您当前的设置之一是将 margin-top 设置为 -25%

http://jsfiddle.net/ycAta/

看起来不太协调的唯一原因是因为位置基于文本顶部,并且存在必要的间隙,因为并非所有字母高度相同。

手动修复的话,-30% 看起来更好。 :P


谢谢,但我不确定这解释了为什么它不像我正在工作的文章那样工作。如果我无法解释它,我就无法说它在不同的浏览器中是否有效。事实上,当我将您的链接加载到IE9中时,我根本看不到文本。 - Jonathan Wood
@JonathanWood 更正:使用 top:25% 而不是 margin-top 更好。但是为什么其他方法不起作用,我不知道。我需要更仔细地研究那篇文章。 - Joseph Marikle
@JonathanWood 这个例子 大致上可以工作(甚至在 IE7 中,据我所知 [IE9 在 IE7 模式下])。再次强调,它是有限的,但基本上假定一个两行高度的内容框,并通过 5% 的不同字母高度进行补偿。 - Joseph Marikle

1

我无法确定为什么我参考的文章中的代码对我无效。有些人提供了答案,但没有一个在各种浏览器中都可靠。

最终,我决定将我的文本保持在一行上,虽然我不太喜欢这种做法。但我确实需要让我的技术清晰明了,并且能够可靠地工作。


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