margin: auto的填充规则:
- 一侧定值(包括不设定值取默认值0的情况),另一侧auto,那么另外一侧的margin为剩余空间大小
- 两侧auto,则平分剩余空间
基于以上规则,可以得出:margin属性的auto可以实现块级元素左中右对齐(且与浮动实现对齐相比为最佳实践)。
<div class="father">
<div class="son"></div>
</div>
.father {
width: 300px;
}
.son {
width: 200PX;
margin-right: auto; /* 左对齐 */
margin-left: auto; /* 右对齐 */
margin: 0 auto; /* 居中对齐 */
}
问题:既然如此,为什么定高定宽的子元素设置margin: auto无法垂直居中?
原因:触发margin: auto计算有一个前提条件,就是width或height为auto时,元素是具有对应方向的自动填充特性的。也就是说,可是通过margin: 0 auto实现水平居中全都是因为元素在水平方向上具有自动填充父元素剩余空间的特性,但在垂直方向是没有这个特性的(我们的文档流方向决定了这一现象)。
解决1:将writing-mode改为verticle-lr,可以实现垂直方向上的居中,但同时, 由于上述原因,水平方向上的居中失效了。这个解决方案不被采纳。
解决2:绝对定位元素的垂直居中,将其“格式化宽度和高度”(这个概念在另一篇flex替代布局中有讲过),令元素在水平和垂直方向上都具有自动填充的特性,就可以通过margin: auto的“触发条件”啦,具体解决方法如下:
.father {
width: 300px;
position: relative;
}
.son {
position: absolute;
top: 0;bottom: 0;
left: 0;right:0;
margin: auto;
}
.son元素对立方位上与父元素的距离都是0,其外部尺寸就会自动填充满父元素的可用尺寸,此时再给子元素设置宽高,就有了剩余的“可用空间”,margin: auto就会起作用了,实现了该元素的水平垂直居中。
【TIPS】上述格式化宽度和高度的操作仅针对于非替换元素,若要将替换元素如此设置,需要额外加上display: block
【兼容性】上述做法IE8/8+支持