若文章有任何纰漏或未涉及你想了解的内容,欢迎在评论提出,我会尽最快速度回复。
更新说明
2019.8.25在制作基于layui的复合菜单时,用到了绝对定位默认位置的特性,故翻出本文进行了修订。
问题情境
关于绝对定位元素的默认位置,我们根据经验或是某些“通行“说法,认为绝对定位元素的默认位置是其第一个非静态定位祖先节点的左上角。
-
这种认知对参考元素的理解是正确的——即绝对定位元素的参考元素是第一个非static定位祖先节点。若祖先元素不存在,则相对于初始包含块,一般为html根节点。
-
但“左上角”的认识是错误的。absolute定位下,left/top默认值是auto,元素并不总出现在左上角——“left 0 top 0”的位置。
造成这种错误认知的原因在于,开发者常常会把绝对定位元素放在非静态定位父容器内的第一个,又或是设置完绝对定位,就一定会设置偏移量,而没有考虑过仅设置absolute定位而不设置偏移量的场景。
那么left/top:auto的计算机制究竟是怎样的呢?
left/top:auto的计算机制
1.W3C规定
- 查阅W3C的CSS2.1文档可知,当不设置盒偏移量时,absolute定位元素的默认位置是假定其为static定位时的位置。
2.验证
为了验证文档中的定义,下面进行两组四个实验:
- 在同一相对定位的容器中(蓝色),静态定位的兄弟元素(橙色)在上,静态定位的测试元素(绿色)在下;
- 静态定位的兄弟元素(橙色)在上,绝对定位的测试元素(绿色)在下;
- 绝对定位的兄弟元素(橙色)在上,静态定位的测试元素(绿色)在下;
- 绝对定位的兄弟元素(橙色)在上,绝对定位的测试元素(绿色)在下;
自变量为测试元素的定位方式——静态定位/绝对定位。
<div class="container">
<div class="brother"></div>
<div class="test"></div>
</div>
实验1
结果如下,静态定位的两个块级元素根据BFC,各占一行。
实验2
当测试元素改为绝对定位以后,它保持了静态定位时的位置
实验3
当兄弟节点为绝对定位,脱离文档流后,静态定位的测试元素顶到了容器的左上角。
实验4
当兄弟节点为绝对定位,测试元素也变为绝对定位后,测试元素仍然保持了静态定位时的位置(但元素的层叠性发生了变化,在同是绝对定位的情况下,节点靠后的测试元素层叠性更高,视觉上覆盖了兄弟节点,有关层叠性,请参考堆叠上下文与z-index
总结
由上述实验可证得,absolute定位元素的默认位置就是该元素假定在标准文档流中的位置。具体地,浏览器先预估该元素在标准文档流中的位置,然后再进行绝对定位,将它移出标准文档流,它并不会自动移到"left 0 top 0"的位置,假如有兄弟元素占位,它的原点也不会出现在父元素内容块的左上角。
附
我用absolute默认位置特性,实现了基于layui的复合菜单,实例即将补充…