CSS sticky定位中margin-box何时不作为position box?示例不符原因
粘性定位position box计算规则实测偏差疑问
W3C在Sticky positioning定义中给出如下规则:
元素的position box默认取其margin box,例外情况为:若某一侧方向上,元素margin edge与其包含块对应边缘的距离小于该方向对应的margin值,则使用该距离替代对应margin值计算position box。
我尝试复现该规则对应的场景,测试代码如下:
.container { height: 100px; background: lightgray; overflow: auto; } .content { background: gray; border: 1px dotted red; } button { position: sticky; top: 40px; margin: 30px 0; } .spacer { height: 300px; }
<div class="container"> <div class="content"> <button>sticky</button> </div> <div class="spacer"></div> </div>
按照我的理解,上述示例中sticky元素的margin edge与其包含块对应边缘的距离为0,小于对应margin值(40px),根据W3C的定义,此时position box不应取margin box,而应为sticky元素自身尺寸加0计算得到的范围。但实际运行示例可见,position box仍然将margin计算在内,为何position box仍与margin box保持一致?
原因解释
你的预期和实际效果不符,核心是两个认知偏差:
- 你混淆了参与比较的数值:规则里和距离做比较的是对应方向的margin值,不是
top/bottom这类粘性定位偏移值。你的示例里按钮上下margin是30px,40px是top设置的粘性偏移阈值,根本不属于margin范畴,不参与这个规则的比较。 - 你没搞懂规则触发的前提:这个例外规则本质是处理「元素的margin边溢出了包含块边界」的场景,只有当margin edge跑到包含块对应边缘的外侧,导致二者距离为负、或者小于对应方向的margin值时,才会触发替换。你的示例里按钮在正常流初始位置时,上margin edge刚好和包含块上边缘重合,整个30px的上margin完全落在包含块内部,根本不满足触发例外的条件,position box自然按默认规则取完整margin box,把30px上下margin都计算在内。
如果要触发这个例外规则,可以构造margin溢出包含块的场景,比如给.content加上margin-top: -10px,此时按钮的上margin edge会位于包含块上边缘外侧10px的位置,二者距离为-10px,小于上margin值30px,这时候上方向参与position box计算的数值就会被替换为-10px,不会按完整的30px上margin计算。
内容的提问来源于stack exchange,提问作者user31782
相关产品推荐
相关产品推荐

