为什么absolute定位会使margin:0 auto失效?

Crushdada
  • 105

题目描述

为什么absolute定位会使margin:0 auto失效?

题目来源及自己的思路

一个小的块套在一个大的块之中
image.png
image.png
百度说是因为绝对定位的元素脱离了文档流,因此会失效。

但是

我并不能从这句话中读出很强的逻辑性,因此如果想要弄清楚这个问题的原理,我需要进一步分析其中的过程


首先
margin:0 auto,在正常情况下是如何实现居中的?

这基于它的填充规则:
(1)如果一侧定值,一侧auto,则auto为剩余空间大小
(2) 如果两侧均是auto,则平分剩余空间

我们可以看到,它是通过平分剩余空间来实现元素水平居中的

然后
对于absolute元素,它脱离了文档流之后相对于谁定位?如何定位?

我们常常可以看到这样的定义:absolute元素是相对于离他最近的已定位的祖先元素进行定位的,这里的“已定位”指该祖先position的值必须是:relative、absolute、fixed。

可以看到在代码中,out块已经设置了relative,那么in块确实是相对于它定位的。

通过偏移量定位

于是我们给子元素的right和left为0,此时就会发现--margin:0 auto 有效了!
image.png

进一步分析
对于一个absolute定位的元素,其左右偏移量设置与否,为什么会影响auto值的计算结果呢?
回复
阅读 463
2 个回答
✓ 已被采纳
  1. 正常布局中,margin:0 auto就相当于top和bottom设置为0,left和right设置为auto
  2. position: absolute会使这个块脱离正常的文档流
  3. 设置top: 0; left: 0; bottom: 0; right: 0;会给这个块提供一个新的边界盒(bounding box)。这种情况下,这个块会填满它的偏移父元素的全部可用空间(偏移父元素:offset parent,指position: relative的父元素或者是body)
  4. 给这个块指定width或者height会阻止它占据全部可用空间,转而由浏览器根据这个新的边界盒自动计算margin
  5. 由于这个块脱离了正常的文档流,同时有一个新的边界盒,因此浏览器可以很容易地为它提供相等的margin-topmargin-bottom值,从而使它垂直居中。
已参与了 SegmentFault 思否「问答」打卡,欢迎正在阅读的你也加入。

具体原因一下子描述不清楚了,但是你可以单独起一个demo然后审查模式下,查看计算出来的盒模型。
1、绝对定位之后,元素脱离文档流,默认的定位还是原先的auto,这个时候元素还是定位在原先的位置上的,粗暴一点的话,可以理解成自动设置成相对于最近的非静态定位的祖先自动设置了原先的 lefttop 的值。
image.png

这个时候如果你设置了 margin 还是会在原有的位置基础上去做偏移。
image.png

2、那如果设置了 left 之类的属性呢,立马就会破坏这个默认的 auto 获取的原先的定位,依照你的设置来做定位,比如说 left:0 就是贴在最近的一个非静态定位的祖先上。
image.png

3、那么如果我同时设置了 left:0right:0 呢?
image.png

乍一看是不是没有效果?让我们把 width:200px 注释掉...
image.png

宽度是不是被拉伸了?同理,我们可以设置固定的 width,然后设置自动的 margin 来达到居中的效果。
image.png

具体原因是,如果你设置了 left:0; right:0; 给元素,那么浏览器就会 尽可能 的去做到把这个元素的左定位和右定位满足0,如果不能满足,则按照 左上右下 的优先顺序来实现布局,那么如果 width 设置成了 auto,则宽度会被拉伸来满足定位,同理如果 margin 设置成为了 auto,则会自动填充外边距来达到布局的效果。
如果我把 widthmargin 都设置成了自动呢? 拉伸 width
image.png

以上,希望可以解答你的疑惑。

参考文章:
position - CSS(层叠样式表) | MDN
left - CSS(层叠样式表) | MDN
absolute绝对定位的非绝对定位用法 « 张鑫旭-鑫空间-鑫生活

已参与了 SegmentFault 思否「问答」打卡,欢迎正在阅读的你也加入。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
你知道吗?

宣传栏