44年前我们把人送上月球,但在CSS中我们仍然不能很好实现水平垂直居中。
水平垂直居中有相同点也有不同点,接下来讨论常见的方式。
如无特殊说明,以下示例html均为:
<div class="md-warp"> <spanclass="md-main"></span> </div>
基础样式为:
.md-warp{ width: 400px; height: 300px; max-width: 100%; border: 1px solid #000; } .md-main{ display: block; width: 100px; height: 100px; background: #f00; }
需要满足三个条件:
display:block
margin-left
和 margin-right
都必须设置为auto .md-main{ margin: 0 auto; }
需要满足三个条件:
left:50%
margin-left
为宽度的一半 .md-warp{ position: relative; } .md-main{ position: absolute; left: 50%; margin-left: -50px; }
有些时候我们的元素宽度可能不是固定的,不用担心,我们依然可以使用定位法实现水平居中,此时需要用到css3中的 transform
属性中的 translate
,可以使元素移动时相对于自身的宽度和高度。
需要注意,这种方法需要IE9+才可以实现。
.md-warp{ position: relative; } // 注意此时md-main不设置width为100px .md-main{ position: absolute; left: 50%; -webkit-transform: translate(-50%,0); -ms-transform: translate(-50%,0); -o-transform: translate(-50%,0); transform: translate(-50%,0); }
不定宽
对于单行文字来说,直接使用 text-align: center
即可。
多行文字可以看作一个块级元素参考margin法和定位法。
和水平居中类似,只是把 left:50%
换成了 top:50%
,负边距和 transform
属性进行对应更改即可。
优点:能在各浏览器下工作,结构简单明了,不需增加额外的标签。
.md-warp{ position: relative; } .md-main{ position: absolute; /* 核心 */ top: 50%; margin-top: -50px; }
运用css3中的clac()属性能简化部分代码:
.md-warp{ position: relative; } .md-main{ position: absolute; /* 核心 */ top: calc(50% - 50px); }
.md-warp{ position: relative; } .md-main{ position: absolute; top: 50%; // 注意此时md-main不设置height为100px -webkit-transform: translate(0,-50%); -ms-transform: translate(0,-50%); -o-transform: translate(0,-50%); transform: translate(0,-50%); }
不定高
需要满足两个条件:
line-height
设置成和 height
的值一样 <div><span>这是一段文字</span></div>
div{ width: 400px; height: 300px; border: 1px solid #000; } span{ line-height: 300px; }
这是一段文字
如果想避免使用绝对定位,我们仍然可以利用 translate()
方法,其值刚好是元宽度和高度的一半。但是,我们如何不使用top和left将元素从top和left移动50%的偏移量呢?
首先想到的是给margin属性一个百分数,像这样:
.md-main{ margin: 50% auto 0; transform: translateY(-50%); }
效果如下所示:
我们发现并没有出现预想的结果,这是因为 margin
的百分比计算是相对于父容器的 width
来计算的,甚至包括 margin-top
和 margin-bottom
。
我们如果仍然想让元素在视窗中居中,还是有救的。CSS3定义了一种新的单位,称为相对视窗长度单位。
以下摘自w3cplus
vw
是相对于视窗的宽度。与你预期刚好相反, 1vw
相当于视窗宽度的 1%
,而不是 100%
vw
相似的是, 1vh
相当于视窗高度的 1%
1vmin
等于 1vw
,反之,如果视窗宽度大于高度, 1vmin
等于 1vh
如果视窗的宽度大于高度, 1vmax
等于 1vw
,反之,如果视窗宽度小于高度, 1vmax
等于 1vh
在上个示例的基础上,我们需要给 margin
设置 vh
单位:
.md-warp{ position: relative; } .md-main{ position: absolute; margin: 50vh auto 0; transform: translateY(-50%); }
注意:这种方法最大的局限是只能适用于元素在 视窗 中垂直居中,如果是在局部的某个地方就无能为力了。
如果不考虑浏览器的兼容性,Flexbox无疑是最好的解决方案,因为它的出现就是为了解决这样的问题。
完成这项工作只需要两个样式,在需要水平垂直居中的父元素上设置 display:flex
和在水平垂直居中的元素上设置 margin:auto
。
.md-warp{ display:flex; } .md-main{ margin: auto; }
Flexbox的实现文本的水平垂直居中同样很简单。
.md-warp{ display:flex; } .md-main{ display: flex; align-items: center; justify-content: center; margin: auto; }
我是字啊
transform-style:preserve-3d
来解决,但这是一个Hack手段,不能保证它不会过时。 以上各种方法稍加组合即可同时实现水平和垂直居中,这些就是平时用到较多的一些居中的方法,希望大家看完之后有收获:)