可能了解包含块的人很少,但有这么个问题,大家可以看看。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.grand {width: 500px;height: 500px;background-color: skyblue;position: relative;}.fa {width: 300px;height: 300px;border: 5px solid black;margin-left: 100px;transform: rotate(0deg);}.son {width: 100px;height: 100px;position: absolute;background-color: red;left: 20px;height: 20px;}</style>
</head><body><div class="grand"><div class="fa"><div class="son"></div></div></div>
</body></html>
在爷爷元素上添加了相对定位,给孙子元素上添加了绝对定位
以正常的一个理解来讲,孙子元素最后是相对爷爷元素来进行位偏移的,但结果却不是
可能有点丑,但结果是显而易见的,孙子元素是相对父元素来进行定位的,那么究竟是为什么呢,这里就需要了解一些包含块的知识点了。
一、什么是包含块
CSS规范中有明确书写(以下是部分截图)
简单理解:就是元素的尺寸和位置,会受它的包含块所影响。对于一些属性,例如width,height,padding,margin,绝对定位元素的偏移值(比如position被设置为absolute或dixed),当我们对其赋予百分比值时,这些值的计算值,就时通过元素的包含块计算得来。
二、分类
1.跟元素所在包含块(初始包含块)
根元素(HTML元素)所在的包含块,被称为初始包含块(initial containing block)。对于浏览器而言,初始包含块的大小等于视口的大小,几点在画布的原点(视口左上角)。它是作为元素绝对定位和固定定位的参照物。
2.非根元素所在包含块
1).前三种可能
另一种是对于非根元素,对于非根元素的包含块判定就有大致三种不同情况:
- 如果元素的positiion是relative或static(相对定位或静态定位),那么包含块由离它最近的块容器(block container)的内容去与(content area)的边缘建立;
- 如果position的属性是fixed(固定定位),那么包含块由视口建立;
- 如果元素使用了absolute(绝对定位),则包含块由它的最近的position的值不是static(也就是值为fixed、absolute、relative或sticky)的祖先元素的内边距区的边缘组成。
但大家看到这里会发现,这里所说的跟自己最一开始所想的结果应该是一样的啊,那么下面就是另外一种可能。
2).另一种可能
那就是如果position属性是absolute或fised,包含块也可能是满足以下条件的最近副局元素的内边距区的边缘组成的:
- transform或perspective的值不是none;
- will-change的值是transform或perspective;
- filter的值不是none或will-change的值是filter(值在Firefox下生效);
- contain的值是paint(例如:cantain: paint;)
相信大叫看完这些就明白产生这个结果的原因了,下面在附加一道例题:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>#div1 {position: absolute;left: 50px;top: 50px}#em1 {position: absolute;left: 100px;top: 100px}</style>
</head><body><div id="div1"><p id="p1">This is text in the first paragraph...</p><p id="p2">This is text<em id="em1">in the<strong id="strong1">second</strong>paragraph.</em></p></div>
</body></html>
大家可以试着分析以下每个元素的包含块(会在评论区附上答案)