居中,虽然只是很普遍很普遍的一种样式,
很不起眼,但是,他却非常考验人。
没有应对一切的方法,只有灵活巧妙地运用。
-
水平居中
我这里把水平居中分成两种,行内元素居中和块级元素居中。-
行内居中
文字居中,最常用简单的了。
text - align: center;
行内元素居中
父子宽高可未知。
父元素text - align: center;
之后,
只要子元素是行内元素(设置成),就可以实现居中,
inlin
/inline - block
/inline - table
/inline
/flex
-
块级元素
子元素有设定宽度
使用自动外边框。
子元素设置margin: 0 auto;
,
左右边框自适应,把元素撑到中间。子元素绝对定位
如果父子都有设定宽度时,是很简单的,直接用定位解决。
但如果只有子元素有设定宽度,父元素宽度未知时,
我们可以用left: 0; right: 0;
把子元素强制扯到父元素一样宽。
然后再设置margin: 0 auto;
,用外边框把多出来的空间填充。-
子元素浮动
如果子元素宽度确定时.item { float: left; width: 100px; //操作 ↓ position: relative; left: 50%; //父元素宽度的50% margin-left: -50px; //自身宽度的一半 }
其实思路就是,先把子元素推到父元素的中间,
然后再把它往回移动自身一半的距离,那么中线就重合了。
如果结构允许的话,还可以用父元素的padding来推。如果宽度不确定呢
把margin-left
属性更换成transfrom: translateX (-50%)
,
因为translate里头的百分比,是相对于自身而言的(桥黑板),
不过用这个会导致一些兼容性问题。还有另一种搞法
给浮动的子元素包裹(或本来存在)上一个父元素,
甚至于父元素都可以是浮动的。
最实际的栗子就是无序列表中,li 浮动,而ul就是包裹的父元素。
ul 的宽度与 li 的整体宽度相等,两者添加position: relative;
然后ul { left: 50%; } li { right: 50%; }
,实现居中。
这就是上面方法的原理图(为了方便看加了点padding)
其实还是那个思路,只是到达中部的方法不一样(被顶和被载)
这种方法好处就是它的兼容性和适用都比较强。 还有一种需要考虑兼容的方法
给父元素设置display: flex; justify-content: center;
使父元素变成一个弹性盒子,然后里面的元素居中显示。
当然,说到flex这个属性,兼容性就比较差了。
文末,我将讲解一下这个属性的兼容性。
-
下面可以来说一说垂直居中了,其实很多思路与水平很相似,
但是垂直居中少了一些属性支持,所以处理起来感觉比较棘手。
注意,最后有个优雅的大招
-
垂直居中
-
行内居中
-
针对单行文本
可以使用父元素设置上下相同的 padding 来实现。
另外,若知道父元素高度,可以将line - height设置与之等高。 -
如果是多行文本
同样可以使用 padding 来撑起,
也可以给父元素设置display: table-cell; vertical-align: middle;
把父元素变成一个表格的单元格。
-
针对单行文本
-
块级元素居中
可能很直观会想到上面最简单的用margin撑开,
然而,再垂直上不存在的,上下外边框并不能自动撑开,除非-
绝对定位
①直接手动定位
②子元素有设定高度(并非自动)
或position: absolute; top: 0; bottom: 0; //强制扯成与父元素一样高 margin: auto 0; //然后再用外边距填充
③所有高度未知position: absolute; top: 50%; heigth: 100px; margin-top: -50px;
这种方法需要考虑兼容性。position: absolute; top: 50%; heigth: 100px; transform: translateY (-50%); //这里的百分比是想对自身的
-
使用flex
display: flex; //父元素成为弹性盒子 flex-direction: column; //盒子里的元素表现为柱状 justify-content: center; //中心对齐
-
大招来了
原理就是用:before来创建一个空的伪元素,只有高度。//首先父元素是这样的(对就是这么寒酸) .box { height: 400px; } //然后子元素 .item { display: inline-block; vertical-align: middle; } //变成行内模块,并垂直对齐,此时居中不了,因为没人跟它对齐呀 //大招来了 .box: before { content: ' '; height: 100%; width: 0; display: inline-block; vertical-align: middle; }
因为垂直对齐需要有参照物,
所以用:before撑起整个高度,然后让元素与它垂直对齐,
自然就是父元素的正中间了。
如果还需要水平对齐,因为已经是inline - block。
只要再父元素上加一个text - align: center;
就可以了。
如果想要解决兼容问题,
可以把伪元素改编成手动添加的div,设置一样的参数就可以了。
有一个问题,就是元素不能沾满整行,
这样会把参照的伪元素挤走,导致无法对其。
-
绝对定位
-
若需要其他居中的(水平垂直居中),可以将以上两个部分的结合。
最好水平和垂直都用同一个方案,这样可以节省代码量并减少冲突。
-
最后我们来看看 flexbox 的兼容性。
参考 阮一峰——Flex 布局教程
Wait me back