css元素水平垂直居中的方法
前言
还记得刚开始出来找工作那段时间,有一次去一家公司面试,结果出了个小项目要当场实现,然后是一个移动端登录界面,要求整体位置水平垂直居中,结果当时基础薄弱,根本想不起来怎么实现水平垂直居中,现在想起来都有点自愧不如。
后面虽然回去详细了查看了一些使元素水平垂直居中的方法,也有所收获,但是也没来得及整理一下具体方法。
实现方法
一般来说,根据元素的宽高是否是固定的还是不定的(即随内容不同而改变),适用的方法也有所不同。
固定宽高的元素
方法一:负margin + position + (50%, 50%)
由于元素本身的宽高是固定的,也就是无论其内容怎么改变,width
和height
是不变的,因此可以直接『计算』出该元素在其父元素内水平垂直居中的位置:正中心位置(即left
和right
都为50%
的位置)向左上角方向偏移自身宽高的一半。如图所示:
关键就在于使用负margin
进行偏移,使元素处于水平居中的位置:
1 | .father{ |
方法二:margin:auto + position + (0,0,0,0)
这种方法实际上利用了margin:auto
这个属性的特点:
1 | margin:auto的填充规则如下。 |
以上来自张鑫旭大佬的《css世界》—— 4.3.4 深入理解CSS中的margin:auto
可以这么理解:当设置元素的left,right,top,bottom
都为0
时,代表该元素实际上可以分配的空间大小为父元素(最近的非static
祖先元素)的全部大小(即自动填充父元素所有空间),但是该元素又设置了width
和height
属性,所以就有所谓的『剩余空间』,利用margin:auto
就可以自动平分『剩余空间』,使『剩余空间』成为margin
。
基本css
形式如下:
1 | .father{ |
方法三:position + calc
这种方法的原理与方法一是相同的,也是先定位到(50%, 50%)
的位置,然后向左上角进行偏移;只不过这里利用了css3
的calc()
方法代替负margin
进行偏移:
1 | .father{ |
可以看出calc()
方法中的%
是相对于父元素(最近的非static
祖先元素)而言的。
不定宽高的元素
所谓的不定宽高就是指元素的width
和height
都没有预先设置,而是随内容不同发生改变(撑开)。既然适用于不定宽高元素的水平垂直居中,那肯定也适用于固定宽高元素。
方法一:flex大法
说句实话,要是css3
完全普及并没有兼容性问题的时候,所有的布局几乎都可以使用flex
伸缩盒模型来完成,根本不用像之前那么麻烦。利用flex
进行水平垂直居中,主要是使用justify-content
和align-items
这两个属性,前者是用来控制主轴元素的排列布局方式,而后者就是用来控制侧轴元素的排列布局方式。而flex
盒模型中默认的主轴就是水平方向,所以可以用justify-content:center;
使元素水平居中,用align-items
使元素垂直居中:
1 | .father{ |
方法二:position + (50%, 50%) + transform
利用css3
的tansform
属性也可以使元素水平垂直居中,其原理和图1
一样,先定位到(50%, 50%)
,然后使用transform
属性中的translate()
方法进行偏移即可:
1 | .father{ |
没错,transform
的%
是相对于自身的宽高而言的,因此无论宽高多少都可以达到水平垂直居中的效果。
不过使用上面方法的时候,我发现如果该元素没有设置宽度(子元素是文本,宽度由内容撑开),那么该元素的最大宽度只能到父元素的50%
(即文本宽度超过50%
时会自动换行)。
后话
查了一些文章和资料后,其实还有一些方法可以实现水平垂直居中;如table
布局以及line-height
+vertical-align
+text-align
,但是我在尝试line-height
方案时,有时会不成功,也不知道原因是啥。
所有的实现效果可以查看:http://xiexuefeng.cc/demo/css_test/centet_center.html
参考文章
- CSS实现水平垂直居中的10种方式(史上最全)
- 《css世界》—— 4.3.4 深入理解CSS中的margin:auto