首页 > 代码库 > 关于使用绝对定位使元素垂直居中的问题

关于使用绝对定位使元素垂直居中的问题

今天学习中遇到了使元素垂直居中的问题,网上一搜至少有8种不同的方法,我只试了使用绝对定位的方法。这一试不要紧,一试就懵逼了。下面我把我遇到的问题说一下。

我刚开始是这么试的:

<!DOCTYPE HTML><html>  <head>    <meta charset="utf-8" />    <title>one</title>        </head>  <style rel="stylesheet" type="text/css">  body{    background-color: pink;    position: relative;  }  #box1 {       background-color: red;      border: 1px solid #ddd;       border-radius: 15px;        box-shadow: 0 3px 18px rgba(0,0,0,.5);      width: 150px;       height: 100px;      margin: auto;       position: absolute;       left: 0; top: 0; right: 0; bottom: 0;        }  </style>  <body>    <div id="box1">        </div>  </body></html>

显示如下:

技术分享

div元素怎么跑上边去了,还只显示了一部分。

研究了一下午终于找出了问题所在。问题就出在我给body元素设置了position:relative。下面解释为什么会出现上图显示的情况。

首先我们看下面例子:

<!DOCTYPE HTML><html><head> <meta charset="utf-8"> <title>绝对定位元素测试</title> <style type="text/css">   div#div1{        position:relative;        width:100px;        height:50px;        background:silver;        }    p.p1{
background:green; padding: 0; margin:0; line-height:1em; width:40px; height: 50px; position:absolute; } </style> </head> <body> <div id="div1"> <p class="p1">we were hero.</p> </div> </body> </html>

显示如下:

技术分享

把上面代码中声明div元素高度的代码删掉,显示结果如下:

技术分享

从上面的实际结果看绝对定位元素不能撑开其包含块,也就是说要明确的声明包含块的高度,否则仅仅希望用绝对定位元素去撑开包含块而使其拥有高度是不能实现的。

回到第一个例子,在我给body元素设置为相对定位后,它就成为绝对定位的div元素的包含块,而我没有给body元素设置高度,所以此时他的高度为0,但注意此时它是有宽度的(body元素没有高度,为什么背景却是body元素的背景颜色呢?这其实是html元素的背景颜色,我没有给html元素设置背景色,所以他使用了body元素的背景色。要是不信你可以给html元素另外设置一个背景色,它就不再显示body元素的背景色了)。

body元素没有高度,而我又设置绝对定位的div的top和bottom为0,同时margin为auto。浏览器为了满足top和bottom为0,就只能计算设置为自动取值的margin-top和margin-bottom的值了。在我设置div元素的高度为100px,边框宽度为1px的情况下,其margin-top和margin-bottom要分别为多少,才能使其上下外边距外边界分别距离body元素的上下内边距(这里其实为0)外边界(这个例子中这两个边界是重合的)为0呢?答案是-51px。为什么?因为body元素的高度为0啊!

水平方向上因为body是有宽度的,浏览器将div元素的margin-left和margin-right设置为(body元素内容区宽度-div元素内容区宽度)/2,所以水平方向上div元素居中了。

那么怎么样才能使div元素垂直居中呢?

有三种方法:

第一种方法,在不改变其他代码的情况下,设置body元素的高度,使其至少不小于视口最大化的高度。

第二种方法,在不改变其他代码的情况下,设置div元素的margin-top和margin-bottom值为其高度的一半,margin-left和margin-right还为auto。这种方法其实有缺陷,如果div元素尺寸太小,相对于大的浏览器视口其看上去在垂直方向上还是不居中。

(看到这里,对于上述两种方法其实把包含块body元素换成其他块级元素,就可以实现绝对定位的div元素在其他元素中的水平垂直居中。)

第三种方法,将body元素的position属性删除,其他代码不变。此时绝对定位的div元素的包含块是根元素,即html元素,html元素自带高度,即浏览器视口的高度(只是猜想,没验证),原理与第一种方法一样,就是明确包含块的高度。这也是网上流行的方法。

PS:用绝对定位的方法使元素水平垂直居中,一定要明确绝对定位元素的高度。

 

关于使用绝对定位使元素垂直居中的问题