css实现垂直居中的几种方法
原文来自:达内培训讲师大智慧(qq409579191)。内容略有更改。
垂直居中相关知识总结
大家好,我今天准备给大家讲的是垂直居中实现方法的总结,我一说这个,可能很多学生会觉得特别简单,但是在我带班的过程中会发现很多同学对这个问题很模糊,真正实现的时候不知道怎么去做,并且在实际的工作中还是会用到很多垂直居中相关的知识,所以我觉得有必要总结一下。
我想先问一下你们能想到的实现垂直居中的方法有哪些?
1、line-height方式
2、Table布局
3、绝对定位之automargin
4、绝对定位之负margin
5、额外div
6、Inline-block方式
7、transform
8、Flex居中(暂无)
我把他们分为了两类,行内元素的垂直居中和块级垂直居中
文本垂直居中:line-height方式、table布局
块级垂直居中:绝对定位之automargin、绝对定位之负margin、额外div、inline-block方式、transform方式、flex居中
公共样式
<style>
.box{
width:500px;
height:200px;
border:1px solid #f00;
position: relative;
}
</style>
一、line-height方式
说明:
该方式只适用于情况比较简单的单行文本,只需要简单地把 line-height 设置为那个对象的 height 值就可以使文本居中了。这种方法在小元素上非常有用,例如使按钮文本或者单行文本居中。
优缺点分析
优点:适用于所有浏览器 无足够空间时不会被截断;
缺点:只对文本有效(块级元素无效) 多行时,断词比较糟糕,可以配合强制回车;
.box1{ line-height:200px; } <div class="box box1"> 我是文本line-height(只限单行) </div>
二、table布局
说明:
display:table此元素会作为块级表格来显示 类似table标签
display:table-cell 此元素会作为一个表格单元格显示 类似td 和 th标签
原理:
利用表布局特点,vertical-align设置为Middle后,单元格中内容中间与所在行中间对齐。
优缺点分析
优点:支持任意内容的可变高度、支持响应式;
缺点:每一个需要垂直居中的元素都会需要加上额外标签(需要table、table-cell两个额外元素)
.box2{ width:200px; display: table; } .box2>span{ display: table-cell; vertical-align: middle; text-align: center; } <div class="box box2"> <span>我是文本display: table-cell vertical-align: middle; (多行也可以)</span> </div>
三、绝对定位之automargin
说明:使用绝对定位要求元素必须设置明确高度。内容超过元素高度时需要设置overflow决定滚动条的出现
resize 属性规定是否可由用户调整元素的尺寸。
注释:如果希望此属性生效,需要设置元素的 overflow 属性,值可以是 auto、hidden 或 scroll。
resize: none|both|horizontal|vertical;
优缺点分析
优点:支持响应式,只有这种方法在resize后仍然居中;
缺点:没有显式设置overflow时,内容超过元素高度时会溢出,没有滚动条;
.box3>.tc{ width:50%; height:50%; position: absolute; top:0; left:0; right:0; bottom:0; border:1px solid #0000ed; margin:auto; word-break: break-all; overflow-y: auto ; } .box3{ width:auto; margin: 0 auto; } <div class="box box3"><div class="tc"> <h2>4position: absolute;+margin:auto;</h2> </div></div>
四、绝对定位之负margin
说明:已知元素高度后,使用绝对定位将top设置为50%,mergin-top设置为内容高度的一半(height + padding) / 2;内容超过元素高度时需要设置overflow决定滚动条的出现;top:50%元素上边界位于包含框中点,设置负外边界使得元素垂直中心与包含框中心重合;
优缺点分析
优点:代码量少、适用于所有浏览器、不需要嵌套标签;
缺点:不支持响应式(不能使用百分比、min/max-width);
五、额外div(可以使用before伪类)
说明:在需要居中的元素外插入一个div,设置外div的height为50%,margin-bottom为内部元素的一半(height+padding)/2。内容超过元素高度时需要设置overflow决定滚动条的出现。
优缺点分析
优点:浏览器兼容性好,支持旧版本ie;
缺点:需要额外元素、不支持响应式;
.box5{ height: 300px; } .box5>.tc{ height: 100px; width: 100px; background: #f3f3f3; border:1px solid darkblue; margin: auto; } .box5:before{ content: ' '; display: block; height:50%; margin-bottom: -50px;// tc的高度的一半 } <div class="box box5"> <div class="tc"> 我是文字 <br/>我是文字 </div> </div>
六、Inline-block
说明:将center元素display设置为inline-block,vertical-align设置为middle,为包含框设置after伪元素,将伪元素display设置为inline-block,vercial-align设置为middle,同时设置height为100%,撑开容器。
原理:为同一行的inline-block元素设置vertical-align:middle,该行内的inline-block元素会按照元素的垂直中心线对齐。
优缺点分析
优点:支持响应式、支持可变高度;
缺点:会加上额外标记;
七、Transform
这是最简单的方法,不近能实现绝对居中同样的效果,也支持联合可变高度方式使用。内容块定义transform: translate(-50%,-50%)必须带上浏览器厂商的前缀,还要加上
top: 50%; left: 50%;
优点:
1. 内容可变高度
2. 代码量少
缺点:
1. IE8不支持
2. 属性需要写浏览器厂商前缀
3. 可能干扰其他transform效果
4. 某些情形下会出现文本或元素边界渲染模糊的现象
.box7{ width:auto; border:1px solid #f000f0; position: relative; } .box7>.tc{ position: absolute; top:50%; left:50%; -webkit-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); -o-transform: translate(-50%, -50%); transform: translate(-50%, -50%); border:1px solid saddlebrown; width: 60%; height: 70%; } <div class="box box7"> <div class="tc"> 我是文字 <br/>我是文字 </div> </div>
八、Flex居中
ul{
list-style: none;
}
li{
border:1px solid #f00;
float: left;
width:200px;
height:100px;
text-align: center;
padding:5px;
box-sizing: border-box;
display: -webkit-flex; /* Safari */
display: flex;
flex-direction: column;
justify-content: center;
}
<ul>
<li><a href="#">首页</a></li>
<li><a href="#">Visitor Notice<br>Visitor Notice</a></li>
<li><a href="#">2016 Annual Fitness Model Contest – the Glorious Shanghai Contest!</a></li>
</ul>
完整代码如下:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no,width=device-width,height=device-height"> <meta name="Author" content="haley"> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>实现垂直居中的几种方法</title> <style> .box{ width:500px; height:200px; border:1px solid #f00; position: relative; } .box1{ line-height:200px; } .box2{ width:200px; display: table; } .box2>span{ display: table-cell; vertical-align: middle; text-align: center; } .tmBox{ display: table;margin: 0 auto; } .tmBox>.tmChild{ display: table-cell; vertical-align: middle; margin: 0 auto; text-align: center; } section{ /*border:1px solid #f0f;*/ } .b1{ width:800px; height:600px; border:1px solid #0f0; } .b2{ border:1px solid #f0f; } .b3{ width: 100%; height: 200px; border:1px solid #00f; } .box3>.tc{ width:50%; height:50%; position: absolute; top:0; left:0; right:0; bottom:0; border:1px solid #0000ed; margin:auto; word-break: break-all; overflow-y: auto ; } .box3{ width:auto; margin: 0 auto; } .box5{ height: 300px; } .box5>.tc{ height: 100px; width: 100px; background: #f3f3f3; border:1px solid darkblue; margin: auto; } .box5:before{ content: ' '; display: block; height:50%; margin-bottom: -50px;// tc的高度的一半 } .box7{ width:auto; border:1px solid #f000f0; position: relative; } .box7>.tc{ position: absolute; top:50%; left:50%; -webkit-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); -o-transform: translate(-50%, -50%); transform: translate(-50%, -50%); border:1px solid saddlebrown; width: 60%; height: 70%; } .box8{ width: auto; display: -webkit-flex; display: flex; justify-content:center;align-items:center; } .box8>.tc{ border:1px solid #f04; width:60%; height:60%; } </style> </head> <body> <div class="box box8"> <div class="tc"> 我是文字8 <br/>我是文字 </div> </div> <div class="box box7"> <div class="tc"> 我是文字7 <br/>我是文字 </div> </div> <div class="box box5"> <div class="tc"> 我是文字5 <br/>我是文字 </div> </div> <div class="box box3"><div class="tc"> <h2>4position: absolute;+margin:auto;</h2> </div></div> <hr/> <div class="box box1"> 我是文本line-height(只限单行) </div> <hr/> <div class="box box2"> <span>我是文本display: table-cell vertical-align: middle; (多行也可以)</span> </div> <section class="b1 tmBox"> <section class="b2 tmChild tmBox"> <section class="b3 tmChild"> 这里的内容居中 </section> </section> <section class="b2 tmChild tmBox"> <section class="b3 tmChild"> 这里的内容居中 </section> </section> </section> </body> </html>