导言:
之前逛社区的时候发现这样一个问题:
https://segmentfault.com/q/1010000007794330
问题下有两种回答,有人说不可以实现,有人说可以实现,并给出了代码示例:
有人说“试了下二楼的那个,貌似可以”,我们可以看一下二楼的代码,可以发现它实现的原因是使用position: absolute;把自己的包含块改变了。
这里就引出了我想分享的内容:视觉格式化模型之包含块。
在日常使用css写页面时我有一些基础的认识,比如:
- 子元素绝对定位,它会相对于最近的非 static定位祖先元素进行定位,left相对于这个元素的左边缘进行计算,top相对于这个元素的上边缘进行计算;
- 元素的width、margin、padding百分比相对于父元素的宽度来计算,元素的height相对于父元素的高度来计算。
这些简单的概念在我刚开始学习css的时候就知道了,并且在后续的学习和开发中,对这些概念都有自然而然的理解。
然而这些说法并不严谨,我发现这些概念并不是一成不变的。
如下:
<style>
.father {
width: 600px;
height: 300px;
background-color: #ccc;
outline: 1px solid red;
}
.son {
width: 50%;
height: 50px;
background-color: red;
}
</style>
<body>
<div class="father">
<div class="son">son</div>
</div>
</body>
子元素的width为50%,是相对于.father元素的宽度,这没问题。但是一旦给.son元素加上绝对定位,我们会发现,子元素的50%就相对于最外层的html元素了。
<style>
.father {
width: 600px;
height: 300px;
background-color: #ccc;
outline: 1px solid red;
}
.son {
position: absolute;
width: 50%;
height: 50px;
background-color: red;
}
</style>
<body>
<div class="father">
<div class="son">son</div>
</div>
</body>
CSS 视觉格式化模型是 CSS 的最基础的概念之一,准确地理解它可以帮助我们在日常开发中少走弯路。
这里我们直接看文档吧。
总结
文档写了很多,总而言之就是:
1、这个知识点对于我们使用css布局很重要;
2、这个模型会根据盒子的包含块(containing block)的边界来渲染盒子,包含块是元素用来计算和定位的一个区域;
3、这个区域是如何来确定的呢:
- 如果这个元素是一个浮动元素或者常规元素,它的包含块是父元素的内容区域(即上图的Content区域);
- 绝对定位元素的包含块是最近的非 static 定位祖先元素的填充盒(即Content+Padding);
- 固定定位分两种情况:
- 这个固定定位的元素的祖先元素都没有使用transform去变形,这个时候它的包含块就是屏幕视口;
- 如果它有一个祖先元素使用了transform,那它的包含块就变成了这个元素的填充盒。