CSS布局是前端开发人员开发人员必备的知识,而有关于水平垂直居中在我们的开发过程中也是最常见的,网上整理归纳的各种情况下的水平垂直居中的文章很多,自己也看了很多,但每次遇到比较复杂的情况时还会去翻一遍之前收藏的文章,找到对应的情况,找到解决的办法,写这篇文章的目的也是想彻底过滤一遍有关方面的知识,牢牢掌握一下,减少查阅文档的时间.
1.单行文本的水平垂直居中
1 2 3
| <div class="wrap1"> 这是一个单行文本的水平居中示例 </div>
|
1 2 3 4 5 6 7 8 9
| html,body{ margin:0; padding:0; } .wrap1{ line-height: 400px; text-align:center; height: 400px; }
|
2.多行文本的水平垂直居中
1 2 3
| <div class="wrap2"> 这是一个多行文本的水平垂直居中,我就是我,是颜色不一样的烟火,天空海阔,要做最坚强的泡沫. </div>
|
1 2 3 4 5 6 7 8
| .wrap2{ width: 200px; height: 200px; text-align: center;
display: table-cell; vertical-align: middle; }
|
3.盒模型的水平垂直居中
padding填充
需要知道容器宽高
1 2 3 4 5
| <div class="wrap3"> <div class="content">
</div> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @wrapWidth: 400px; @contentWidth:100px; .wrap3{ margin:0 auto; width: @wrapWidth; height: @wrapWidth; } .content{ width: @contentWidth; height: @contentWidth; padding: (@wrapWidth-@contentWidth)/2; // 也可以用css3的calc()动态计算: padding: -webkit-calc(~"(100% - 100px) / 2"); padding: calc(~"(100% - 100px) / 2"); background-color: #333; background-clip: content-box; } /*这里在calc中使用了一个~""的写法,这是less中的一个语法,告诉less这里不被less所编译,要是被less编译了的话,css的calc函数的参数就不是100% - 100px,而是0%了。*/
|
margin填充
1 2 3 4
| <div class="wrap4"> <div class="content"> </div> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @wrapHeigth: 400px; @contentHeight: 100px; .wrap4{ overflow: hidden; width: 100%; height: @wrapHeigth; } .content{ margin-left: auto; margin-right: auto; margin-top: (@wrapHeight - @contenHeight) / 2; width: @contenHeight; height: @contenHeight; background-color: #333; }
|
4.absolute布局上下文下的水平垂直居中
主要原理就是利用left:50%将盒子的左边先置于父容器的中点,然后再将盒子往左偏移盒子自身宽度的50%,这里有三种具体实现:
1 2 3 4 5 6 7 8 9 10 11 12 13
| <div class="wrap5"> <div class="ele margin">水平垂直居中水平垂直<br>居中水平垂直居中水平<br>垂直居中水平垂直居<br>中水平垂直居中</div> </div>
<div class="wrap5"> <div class="ele translate">水平垂直居中水平垂直<br>居中水平垂直居中水平<br>垂直居中水平垂直居<br>中水平垂直居中</div> </div>
<div class="wrap5"> <div class="ele relative"> <div class="ele-inner">水平垂直居中水平垂直<br>居中水平垂直居中水平<br>垂直居中水平垂直居<br>中水平垂直居中</div> </div> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| .wrap5{ position: relative; width: 100%; height: 200px; border:1px solid; background-color: #ccc; .ele{ position: absolute; left: 50%; top: 50%; background-color: #333; &.margin{ width: 160px; height: 100px; margin-left: -80px; margin-top: -50px; } &.translate{ -webkit-transform:translate3d(-50%, -50%, 0); transform:translate3d(-50%, -50%, 0); } .ele-inner{ position: relative; left: -50%; top: -50%; width: 100%; height: 100%; background-color: #333; } &.relative{ width: 150px; height: 100px; background-color: transparent; } } }
|
上面三个方法中,margin方法和relative方法都需要知道元素的宽高才行(relative方法只知道高也行),适用于固定式布局,而transform方法则可以不知道元素宽高.
相同原理还有一种方法,多用来做遮罩窗
1 2 3 4 5
| <div class="wrap6"> <div class="content">
</div> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| .wrap6{ position: relative; width: 100%; height: 100%; .content{ position: absolute; top: 0; bottom: 0; left: 0; right: 0; width: 100px; height: 100px; background-color: #ccc; } }
|
适用于图片居中的网易nec的一种方法
1 2 3 4 5 6
| <div class="wrap7"> <p> <img src="http://nec.netease.com/img/s/1.jpg" alt="" /> <img src="http://nec.netease.com/img/s/1.jpg" alt="" /> </p> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| .wrap7{ position: relative; width: 100%; height: 100%; p{ position: absolute; left: 50%; top: 50%; img{ &:nth-child(1){ position:static; visibility: hidden; } &:nth-child(2){ position: absolute; right: 50%; bottom: 50%; } } } }
|
这种方法主要是利用了一个图片进行占位,以让父容器获得高宽,从而让进行-50%偏移的图片能有一个参照容器作百分比计算。优点是可以不知道图片的大小,随便放张尺寸不超过父容器的图片上去都能做到居中。另外,兼容性好,如果是不使用nth-child选择器的花,IE6都是能顺利兼容的.但是要注意p的区域问题.
5.float布局上下文下的水平垂直居中
1 2 3 4 5 6 7
| <div class="wrap8"> <div class="ele"> <div class="ele-inner">
</div> </div> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| .wrap8{ float: left; width: 100%; height: 400px; .ele{ float: left; position: relative; left: 50%; top: 50%; .ele-inner{ position: relative; left: -50%; transform: translate3d(0,-50%,0); background: #ccc; } } }
|
实现原理:首先是利用float属性将需要居中的元素的父元素.ele的宽度收缩,然后left:50%将.ele的左边和水平中线对齐,这个时候还没居中,还需要将其往回拉自身宽度的50%,于是.ele-inner便是真正需要水平居中的元素,我给它一个position:relative,将其往回拉自身宽度50%就行了。对于垂直方向,依然是先将.ele top:50%到垂直方向中点,但是这时给.ele-inner top:50%是不起作用的,因为如果没给父元素明确高度的话,这个50%是计算不出来的,因此,就有了transform : translate3d(0, -50%, 0)。
这种方法的好处是元素可以不定宽,任何时候都可以做到居中.
1 2 3 4
| <div class="wrap9"> <div class="placeholder"></div> <div class='content'></div> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| .wrap9{ float: left; width: 100%; height: 400px; background-color: #ccc; @contentHeight : 100px; .placeholder{ float: left; width: 100%; height: 50%; /*居中元素.content高度一半*/ margin-bottom: -(@contentHeight / 2); } .content{ position: relative; left: 50%; transform:translate3d(-50%, 0, 0); clear: both; /*演示用,实际不需要定宽*/ max-width: 100px; height: @contentHeight; background-color: #333; } }
|
这种方法是先让占位元素.placeholder占据50%高度,然后给一个居中元素高度一半的负的margin-bottom,然后下面的元素只要跟着摆放就能垂直居中了。水平方向就是利用translate做偏移,这个没什么好说的,你也可以换成其他办法。
这种方法就是各种固定死,首先最外层的父容器需要一个固定高度,以让.placeholder的height:50%有效,然后,margin-bottom也需要固定死,而且得需要知道居中元素高度。单纯就水平方向来说,这个方法比较适合需要兼容低版本IE的固定式布局的项目,因为兼容性好.
6.IFC布局上下文下的水平垂直居中
1 2 3 4
| <div class="wrap10"> <div class='placeholder'></div> <div class="ele"></div> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| .wrap10{ width: 100%; height: 400px; /* min-height: 400px; */ text-align:center; font-size: 0; background-color: #ccc; .placeholder, .ele{ vertical-align: middle; display: inline-block; } .placeholder{ overflow: hidden; width: 0; min-height: inherit; height: inherit; } .ele{ width: 100px; height: 100px; background-color: #333; } }
|
这里首先是用text-center让inline-block水平居中,然后给一个vertical-align:middle,但是仅仅给vertical-align:middle是不够的,因为此时它还没有vertical-align对齐的参照物,所以就给了一个占位的inline-block,它的高度是100%。
这个方法对于居中元素不需要定宽高,而且元素根据vertical-align值的不同不仅仅可以实现居中,还可以将其放在上面下面等。缺点是父元素需定高.