话说,面试官都喜欢问一个问题,“怎么让一个元素(比如图片)水平垂直居中(😏)”,我感觉这个题目可以考察到很多不同的CSS属性的以及相互作用,于是我就把这道题出给了刚接触前端的学弟们,要求是方法越多越好,然后来源不限,但是要自己理解。然后今天我就收到了一个意外的答案:
.img-center {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}
说意外是我完全没试过,于是写个Demo试试,完美实现,于是去找了找,看到张鑫旭大大的文章 ,顺便也研究了下原理。
说起来,看到这个写法,我想到了两个东西,一个是用position: absolute;或position: fixed;搭配left,top,right,bottom去实现一些一边稀奇古怪的布局,比如一栏顶宽,一栏自适应什么的。然后另一个就是一个常用的水平居中写法:
.center {
display: block;
width: 480px;
margin: 0 auto;
}
这个的原理目测是来自这一条⬇
10.3.3 Block-level, non-replaced elements in normal flow
If both ‘margin-left’ and ‘margin-right’ are ‘auto’, their used values are equal. This horizontally centers the element with respect to the edges of the containing block.
如果 margin-left 和 margin-top 都是auto,那么它们取相等的值…
然后刚刚提到的水平垂直居中的部分在这里⬇
10.3.7 Absolutely positioned, non-replaced elements
If none of the three is ‘auto’: If both ‘margin-left’ and ‘margin-right’ are ‘auto’, solve the equation under the extra constraint that the two margins get equal values, unless this would make them negative …
https://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width
就是说,如果left,right,width,都不是auto,并且margin-left和margin-right都是auto,那么margin取相等的值,除非这会导致它们取到负值。 然后如果没有left和right的话,在仅有width的情况下,left会取0(ltr),元素就居左了。 同时如果left和right为有值,margin平分的是减掉width和left以及right的值(其实还有padding和border)。
10.6.4 Absolutely positioned, non-replaced elements
If none of the three are ‘auto’: If both ‘margin-top’ and ‘margin-bottom’ are ‘auto’, solve the equation under the extra constraint that the two margins get equal values.
https://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width
这一段跟前一段差不多,不过是margin-top和margin-bottom。
然后审查元素看看:

【✔】确实是通过margin居中的。
最后,放一个复杂版本,来看下在有各种复杂属性的情况下的计算结果,注意left值:

🔮