我一直记忆的是
position:relative是相对于父级元素定位的,今天才发现原来自己记错了。
也想明白了绝对定位的元素使用margin:auto为什么可以实现垂直居中
今天早上心有点静不下来,就去 SegmentFault 上看了看文章,有一篇文章 【“寒冬”三年经验前端面试总结之 CSS 篇】,
里边的 垂直居中的方法四 我觉得挺奇怪的。
.outer {
position: relative;
}
.inner {
width: 100px;
height: 100px;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
}
为什么在 position:absolute 时,top,right,bottom,left 都为 0 时,使用 margin:auto 可以实现垂直居中。
是因为脱离文档流了还是因为别的?然后在群里讨论了下。
有些人说,absolute 之后变成行内块元素了,有些人说因为 margin。
然后我又试了下 relative 、 fixed 和 sticky。
只有 absolute 和 fixed 这种脱离文档流的可以使用 margin:auto来居中。
设置了 left,right为 0 所以可以水平居中,top,bottom为 0 可以使其垂直居中
归根结底是因为 margin:auto 填充了外部空间,然后定位是按照合模型最边界开始定位,即从 margin 开始。

另外还把自己一直以来记错的给掰了回来:
position:relative是相对未定位前的元素自身来定位的。
我一直记忆的是相对于父级做定位。
以上
2019 年 11 月 20 日
2021年7月31日更新:
今天在写 数据大屏 “炫酷” 容器边框实现 的时候,突然发现 position:absolute 的定位起始点其实不是从定位祖先的左上角开始的,而是去除 border-width 的,小伙伴们请留意哦。
演示例子 🌰 CodePen link
顺便在补充一下,如果定位的值是百分比,那么这个百分比值是通过其 定位祖先 的 content + padding 值来计算得出的,比如说:
.father{
width: 1000px;
height: 1000px;
padding: 50px;
border: 50px solid red;
position: relative;
box-sizing: content-box; /* 默认盒模型 */
}
.sub{
width: 100px;
height: 100px;
position: absolute;
left: 10%; /* 等同于 left:110px */
}
为什么等于 left:20px?因为父级容器的 width 被 border-area 和 padding-area 撑开了,但是不计算 border-area,
所以 left = (contentWidth + paddingWidth*2) * 10% = (1000px + 50px*2) * 10% = 110px
如果把上边的例子的 .father 的盒模型改成 border-box 那么:left: 10% 就等于 left: 90px 了。
为何?
因为把和模型修改成 border-box 之后,CSS中设置的 width 就等于 border-area + padding-area + content-area 的总和,而因为 width、border-width 和 padding-width 是固定值,所以 content-area 就会被压缩。
所以在计算 left 百分比值时需要减去边框所占用的宽度,既是 left = (width - borderWidth*2) * 10% = (1000px - 50px*2) * 10% = 90px