前几天去一家互联网公司面试,面试官问到了这个应该算是比较简单的问题,在我自认为回答正确时,才知道这道题的答案有不少种,下面就让咱们一块儿来探讨一下这个问题:css
这个是我回答出来的,也是被各位所熟知的一种方法,设外层div相对定位,内层div绝对定位,top、left分别设为50%,而后经过设置margin-top、margin-left值为宽度的负数就能够成功实现垂直水平居中了:html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> *{margin: 0;padding:0;} .outer{ width: 80%; height: 400px; background: #ccc; margin: 0 auto; position: relative; } .inner{ width: 400px; height: 300px; background: green; position: absolute; top: 50%;left: 50%; margin-top: -150px;/*设为高度的1/2*/ margin-left: -200px;/*设为宽度的1/2*/ } </style> </head> <body> <div class="outer"> <div class="inner"></div> </div> </body> </html>
很常见的,这个经典的方法最大的不足之处是inner的宽度必须是固定值,不然margin-top和margin-left的值将没法设置,为了解决这个问题,咱们考虑将使inner发生位移的代码由margin-top、margin-left换成其余形式,换成什么呢?请看第二种方法:css3
咱们的目的是让inner在top和left方向发生50%偏移以后,再往回偏移必定距离,而css里关于位置偏移的属性还有什么呢?当咱们查阅最新版的css3属性以后,发现这样一个属性:selector{transform:translate();}
,translate表明着水平、垂直方向上的转换(位移),其中当括号内的值设为百分比时,将以元素自身宽度为基准,移位相应的宽度,这样一来,咱们的问题就获得了解决:面试
<style type="text/css"> *{margin: 0;padding:0;} .outer{ width: 80%; height: 400px; background: #ccc; margin: 0 auto; position: relative; } .inner{ width: 70%; height: 300px; background: green; position: absolute; top: 50%;left: 50%; transform: translate(-50%,-50%);/*在水平和垂直方向上各偏移-50%*/ } </style> <body> <div class="outer"> <div class="inner"></div> </div> </body>
这个方法妥善解决了内层div宽度不肯定的问题,但因为使用了css3的新属性,在低版本ie浏览器下是不兼容的。由此,咱们想到了第三种方法:浏览器
<style type="text/css"> *{margin: 0;padding:0;} .outer{ width: 80%; height: 400px; background: #ccc; margin: 0 auto; position: relative; } .inner{ width:70%; height: 300px; background: green; position: absolute; top: 0;left:0;right:0;bottom:0;/*让四个定位属性都为0*/ margin:auto;/*很关键的一步*/ } </style>
这个方法,不只能在inner宽度不肯定时发挥做用,还能兼容各类主流浏览器,看上去彷佛很完美,但事实上,当咱们的需求改成:宽度随内部文字自适应 ,即宽度未设置时,这种方法就没法知足需求了,缘由是left、right设为0后,inner在宽度未设置时将占满父元素的宽度。wordpress
(你能够在思路二的基础上将inner宽度去掉,内部放一些文字,你会发如今第二种思路下这种需求是能够知足的)布局
flex布局是移动端一种很新潮的布局方法,利用flex布局使元素垂直水平居中,缺点依然是使人头疼的兼容性问题(在ie11-中不起做用),优势是代码量比前几种方法相比略少,方便使用。
让咱们一块儿来了解一下:flex
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> *{margin: 0;padding:0;} .outer{width: 80%;height: 400px;background: #ccc;margin:0 auto; display: flex;/*设置外层盒子display为flex*/ justify-content:center;/*设置内层盒子的水平居中*/ align-items:center;/*设置内层盒子的垂直居中*/ } .inner{display: inline-block;height: 300px;background: yellow;} </style> </head> <body> <div class="outer"> <div class="inner">这是一段文字这是一段文字这是一段文字</div> </div> </body> </html>
以上就是使div垂直+水平居中的四种方式,关于第三种思路中inner没法对内容自适应的问题,目前我尚未想出解决办法,但愿高人们可以指点一二。code