IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

终极攻略――未知高度元素垂直居中

记事本 2010-07-27 23:33:38 累计浏览 3,700 次
本机暂存

有的同学看到题目就会想:我把父元素设成display: table-cell; vertical-align: middle不就行了吗?很不幸,IE6下没有display: table-cell这个玩意,所以本攻略中一概不讨论上述方式实现的居中。本攻略中,要垂直居中的元素分以下三种情况:

  1. 块级元素
  2. 不可替换(non-replaced)的行元素
  3. 可替换(replaced)的行元素

如果上面说的概念不是很清楚,请参考一下w3的文档。

一,块级元素垂直居中。

因为是未知高度的块元素,通常来说没有办法用绝对定位的方式使它居中。最好的办法是把它变成行内块元素(display: inline-block),这样的话就变成了类似第三种情况:可替换的行元素垂直居中

二,不可替换的行元素垂直居中。

这种情况恐怕是最简单的了,比如:

以下是代码片段:
<div style="height: 300px;line-height: 300px;">
  <span>我要垂直居中啊。</span>
</div>

只要把div的行高(line-height)设成高度(height)一样就可以了,span会自动补白(leading),占满div的高度,以达到垂直居中对齐的效果。这个方法对一行里有多个non-replaced inline elements的情况也是适用的。这里要注意,如果内容太长导致换行的话,这个方法就不适用了,碰到这种情况可以先把元素变为display: inline-block,然后再参考第三种情况:可替换的行元素垂直居中

三,可替换的行元素垂直居中。

如果出现这种情况:

以下是代码片段:
<div style="height: 300px;line-height: 300px;">
  <span>我要垂直居中啊。</span>
  <span>我也要垂直居中。</span>
  <input type="text" />
</div>

上面的代码中,前两个span是不可替换元素,后面的input是可替换元素。在标准浏览器下看,一切正常,可是换到IE6下,情况就不同了,你会发现,这三个元素全都跑到上面去了。这是一个IE6的BUG,简单的说,如果一行中有某些可替换元素,那么IE6会把这一行上面的补白(half-leading)给去掉。如果你打算深入研究,请看http://www.positioniseverything.net/explorer/lineheightbug.html

方法一:

在上述情况下,如果你要兼容IE6,就不得不使用HACK,IE的CSS下面有个特殊的属性writing-mode,它可以改变流的书写方向,我们就用它来做这种垂直居中的事情。拿上面的例子来说,先给input加个容器(用行内元素,这样不会改变FF下的布局):

以下是代码片段:
<div style="height: 300px;line-height: 300px;">
  <span>我要垂直居中啊。</span>
  <span>我也要垂直居中。</span>
  <span class="tmp"><input type="text" /></span>
</div>

然后针对IE6写HACK:

以下是代码片段:
<!--[if IE 6]>
<style type="text/css">
  div .tmp {
    /* 这里的height要和外层容器的行高一致,
       如果内容只有一行的话,可以直接用height: 100% */
    height: 100%;
    writing-mode: tb-rl;
    text-align: center;
    vertical-align: middle;
  }
</style>
<![endif]-->

方法二:

这种居中方案,可以说是万能的。如果方法一可以解决问题,请尽量不要用此方法,毕竟增加了一个没有意义的空标签是很不爽的。

请看如下代码:

以下是代码片段:
<div style="height: 400px;">
  <img src="http://www.xxxxxx.com/摄影作品1.jpg" alt="" />
</div>

上面的img元素是可替换元素,它有固有的高度和宽度(由图片大小决定)。就目前的布局来说,vertical-align对它还不能起到居中对齐的作用,因为它没有占满父级div所有的高度。有的同学就说了:好办,我给img来个line-height。这样是不行的,因为它是可替换元素。难道没有办法了吗?有的,我们知道一行在屏幕上实际占有的高度,是由这行里最高的行级元素决定的(还有多种决定因素),而其它比较矮的行元素通过设置vertical-align: middle就会在这行里垂直居中对齐。通过上一点分析,我们就在img的后面加上一个空的行级元素,让它占满div的高度。这个任务交给inline-block级别的元素完成,因为它可以设高度,而且又是行布局。完整代码如下:

以下是代码片段:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <title>垂直居中</title>
 <style type="text/css">
 #container {
  border: 1px solid black;
  text-align: center;
  height: 500px;
 }
 #container b {
  display: inline-block;
  height: 100%;
  vertical-align: middle;
 }
 </style>
</head>
<body>
 <div id="container">
   <img src="http://img1.cache.netease.com/img09/logo/logo.gif" alt="logo" />
   <b></b>
 </div>
</body>
</html>

这种方法也适合一行中同时出现non-replaced elements和replaced elements的情况。

同分类推荐文章

  1. translateZ() (2026-06-25 21:18:56)
  2. translateY() (2026-06-25 21:17:56)
  3. translateX() (2026-06-25 21:16:01)

查看更多 前端 文章 →

建议继续学习

  1. 50个活力和动感的网页设计-颜色的灵感 (累计阅读 34,437)
  2. 视觉设计前瞻实用性研究(PNVD) 第二期 (累计阅读 12,973)
  3. 各公司对前端开发的职位描述 (累计阅读 10,402)
  4. iframe大小自适应 (累计阅读 10,055)
  5. 浏览器的渲染原理简介 (累计阅读 8,367)
  6. 解决IE6从Nginx服务器下载图片不Cache的Bug (累计阅读 8,352)
  7. 程序员眼里IE浏览器是什么样的 (累计阅读 8,004)
  8. 2010网页设计趋势 (累计阅读 7,815)
  9. Web前端工程师编程能力飞升之路 (累计阅读 7,686)
  10. 颜色的代码表达式 (累计阅读 7,663)