如何在CSS中实现垂直+水平居中?

7
我经常想要在另一个CSS盒子内垂直和水平地居中一个盒子。最简单的方法满足以下约束条件是什么?
  • 盒子应该精确居中,而不是大致。
  • 该技术应在现代浏览器和IE版本(返回到8)中起作用
  • 该技术不应依赖于明确知道居中内容或包含框的宽度或高度。
  • 我通常知道容器比内容大,但支持更大的内容(然后对称溢出)会很好...
  • 容器的基础内容仍必须能够响应点击和悬停,除非被居中内容遮挡

我目前使用4个嵌套的div来实现这一点,css如下:

.centering-1 {
    position:absolute;
    top:0; left:0; right:0; bottom:0;
    text-align:center;
    visibility:hidden;
}
.centering-2 { 
    height:100%; 
    display:inline-table; 
}
.centering-3 { 
    display:table-cell; 
    vertical-align:middle; 
}
.centering-content { 
    visibility:visible; 
}

你可以看到这个jsbin片段中的效果。然而,尽管可行,这种方法感觉像是极度过度设计,并且不适用于大于容器的内容。如何在CSS中居中物品?

我也在想同样的事情。 - Captain Skyhawk
1
有许多方法可以水平对齐元素,即使您不知道要居中的元素的宽度,但是垂直居中高度未知的元素则更加棘手。display: tabledisplay: table-cell + vertical-align: middle 是最简单和最无麻烦的纯 CSS 方法。您可以简化CSS/HTML标记,无需像5个嵌套的div那样。在处理未知尺寸时,这确实是不使用Javascript的主要方法。 - Ennui
1
这个问题可能更适合 http://codereview.stackexchange.com/。 - cimmanon
1
@j08691 原帖明确指出为 IE8。直到版本10,Internet Explorer 才支持该浏览器。 - cimmanon
1
@FreshPrinceOfSO(和cimmanon):我不想让这段代码被审查,我想要在没有我的代码的情况下垂直+水平居中。此外,考虑到我经常遇到这个问题的变化形式,我希望这个问题的答案对其他人也有用——所以我认为这不是一次代码审查。 - Eamon Nerbonne
显示剩余6条评论
2个回答

2
你可以用两个元素完成。任何少于这个数量的元素都需要使用IE8(和IE9)不支持的东西。 http://cssdeck.com/labs/0ltap96z
  <div class="centering-1">
    <div class="centering-2">
      <div class="intrinsically-sized-box">
        <p>You can put any content here too and the box will auto-size.</p>
      </div>
    </div>
  </div>

CSS:

body {max-width:750px;}
.generalblock {
  margin-top:2em; 
  position:relative;
  padding:10px;
  border:20px solid cyan;
  font-size: 18px;
}

.centering-1 {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  text-align:center;
  visibility:hidden;
  display: table;
  width: 100%;
}
.centering-2 {
  display:table-cell;
  vertical-align:middle;
}
.intrinsically-sized-box {
  visibility:visible;
  max-width:300px;
  margin: 0 auto;
  background: yellow; 
  position:relative;
  border:1px solid black;
}

这似乎没有进行垂直居中,至少在Chrome和FF中,黄色框显示在容器顶部。 - Eamon Nerbonne

2

水平居中很容易:

.inner {
  width: 70%; /* Anything less than 100% */
  margin-left: auto;
  margin-right: auto;
}

但是垂直居中有点棘手。现代浏览器最好的技术是结合inline-block和伪元素。这源自于“Ghost element”,即http://css-tricks.com/centering-in-the-unknown/上的最后一种技术。它添加了一个伪元素并使用inline-block样式来实现居中。

CSS代码:
.outer { 
  height: 10rem; 
  text-align: center; 
  outline: dotted black 1px; 
}

.outer:before { 
  content: ''; 
  display: inline-block; 
  height: 100%; 
  vertical-align: middle;
}

.inner { 
  width: 10rem; 
  display: inline-block; 
  vertical-align: middle;
  outline: solid black 1px; 
}

在 Codepen 上有一个示例:http://codepen.io/KatieK2/pen/ucwgi
对于简单的情况,以下可能是不错的选择:
对于单行内容,您可以通过使用行高大于字体大小来快速并粗略地垂直居中元素内的文本:
.inner { 
  border: 1px solid #666; 
  line-height: 200%;
}

最广泛支持的解决方案是使用非语义化表格。这适用于非常旧的IE版本,不需要JavaScript:

td.inner { 
  vertical-align: middle; 
}

以下是针对已知高度元素(可能以em为单位,而非px)的简单解决方案:

.outer { 
  position:relative; 
}
.inner { 
  position: absolute; 
  top:50%; 
  height:4em; 
  margin-top:-2em; 
  width: 50%; left: 25%; 
}

那个幽灵元素技术听起来非常不错! - Eamon Nerbonne
嗯,但是它只在.outer元素有明确的高度时才起作用;这不是一个大问题,因为.outer可以绝对定位以具有100%的宽度/高度。此外,为了避免奇怪的边缘情况,看起来您需要向内部框添加例如最大尺寸(并且使用box-sizing或无边框和填充)以确保当容器变小于内容时,您会得到合理的行为而不是完全混乱的布局。仍然,这看起来非常有前途! - Eamon Nerbonne
不错的奖励:如果在“outer”和“inner”之间不留空格,则无需使用hackish的“margin-right: 0.25em”。 - Eamon Nerbonne
1
我已经将你的幽灵元素技术放入了一个 jsbin 示例中,如果有人想看看它是如何工作的。 - Eamon Nerbonne
1
还有一个问题:与许多“inline-block”技巧一样,.outer.inner的开放标签之间不能有空格,否则水平居中将稍微偏移。您的codepen示例展示了这种不对称性;尝试使列几乎与.inner一样小以查看它。这是一个容易犯的错误,因此需要提醒一下。哦,在.outer上不需要填充。 - Eamon Nerbonne
显示剩余5条评论

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