what
- 一个页面由需要的盒子组成,而每个盒子的类型由display来决定
- 值为【block、list-item、table等】的元素生成block-level box
- 值为【inline、inline-block、inline-table等】的元素生成inline-level box
- 值为【?】的元素生成run-in box
- flex或inline-flex => flex container
- grid或inline-grid => grid container
- 而
不同类型
的盒子会在不同的Formatting context
下按不同的规则渲染
Block formatting context(BFC)
what
- BFC是一个
独立
的渲染区域,规定
了内部的Block-level box如何布局 - 创建BFC的方式
- 常见如下:
- 根元素(html)
- 浮动元素(float不为none)
- 绝对定位元素(position为absolute或fixed)
- overflow计算值不为visible
- display为inline-block,flex,inline-flex,grid,inline-grid等
BFC的布局规则
-
BFC
内部的盒子
从包含块
的顶部,一个接着一个地放置垂直排列
-
两个盒子垂直方向的距离由margin决定
同一个BFC
的相邻块盒子垂直方向
的marign会重叠
-
BFC中每个盒子的
左margin
紧挨着包含块的左border
(对于从右到左的格式,右margin紧挨右border)—— 【包含浮动元素】(尽管框的行框可能会因浮动而缩小),除非盒子建立了新的BFC(在这种情况下,框本身 可能会因浮动而变窄)- 给BFC中某个盒子创建新的BFC,那么它就不属于原先的BFC,即它是独立的了,与外界互不影响
-
计算
创建BFC的盒子高度
时会将浮动元素
也计入其中
总结:BFC就是页面上的一个隔离的
独立容器
,与外界互不影响
使用场景
浮动子元素令父元素高度坍塌
- 根据BFC创建规则,根元素(html)会创建相应的BFC,类名为.container的父元素和类名为.box的子元素属于
同一个BFC
,但是由于.box子元素是浮动元素
,而父元素
本身也没有指定高度
,因此父元素没有相应的高度(即高度坍塌
情况)
.container {
border: 5px solid red;
overflow: hidden;
}
.box {
float: left;
width: 200px;
height: 200px;
background-color: yellow;
}
复制代码
<div class="container">
<div class="box"></div>
</div>
复制代码
- 解决思路:利用BFC布局规则中的【
计算创建BFC的盒子高度时,浮动元素也参与其中
】- .container元素创建BFC,然后计算.container元素的高度时,虽然本身没有指定高度,但是会将浮动元素.box的高度也计入其中,所以`高度坍塌的情况就不出现了
.container {
border: 5px solid red;
overflow: hidden;
}
.box {
float: left;
width: 200px;
height: 200px;
background-color: yellow;
}
复制代码
<div class="container">
<div class="box"></div>
</div>
复制代码
属于同一个BFC的相邻盒子垂直方向margin重叠
- 因为.box1元素和.box2元素都属于同一个BFC(即html创建的BFC),因此它们margin会发生重叠
.box1 {
width: 100px;
height: 100px;
background: blue;
margin-bottom: 50px;
}
.box2 {
width: 100px;
height: 100px;
background: red;
margin-top: 150px;
}
复制代码
<div class="box1"></div>
<div class="box2"></div>
复制代码
- 解决思路:【两个盒子垂直方向的距离由margin决定。同一个BFC
的相邻块盒子
垂直方向的
marign会重叠】,给任意一个元素包裹一个BFC下的父盒子
- 这样的话,.box1元素和.box2元素就属于两个不同的BFC了,它们间
互不影响
,因此margin就不会重叠了
- 这样的话,.box1元素和.box2元素就属于两个不同的BFC了,它们间
.box1 {
width: 100px;
height: 100px;
background: blue;
margin-bottom: 50px;
}
.box2-container {
overflow: hidden;
}
.box2 {
width: 100px;
height: 100px;
background: red;
margin-top: 150px;
}
复制代码
<div class="box1"></div>
<div class="box2-container">
<div class="box2"></div>
</div>
复制代码
非浮动元素被浮动元素覆盖
- 由于BFC中每个盒子的
左外边框
紧挨着包含块的左边框
(包含浮动元素)- 表现为.box2元素紧挨着body元素
.box1 {
width: 50px;
height: 50px;
background: blue;
float: left;
}
.box2 {
width: 100px;
height: 100px;
background: red;
}
复制代码
<div class="box1"></div>
<div class="box2"></div>
复制代码
- 解决思路:给非浮动元素创建一个新的BFC,因为BFC作用的渲染区域是独立的,它不会受到外界影响(由html创建的BFC要求每个盒子的左外边框紧挨着包含块的左外边框,它不受影响),而自身的布局也不会影响到外界
- 即浮动元素能
看得见
有文字特性的元素(inline、inline-block等),而看不见
块级元素
- 即浮动元素能
.box1 {
width: 50px;
height: 50px;
background: blue;
float: left;
}
.box2 {
width: 100px;
height: 100px;
background: red;
display: inline-block;
/* overflow: hidden */
}
复制代码
<div class="box1"></div>
<div class="box2"></div>
复制代码
- 利用
该特性
+width的默认值100%
来实现两栏自适应布局
.box1 {
width: 50px;
height: 50px;
background: blue;
float: left;
}
.box2 {
height: 100px;
background: red;
/* display: inline-block; */
overflow: hidden
}
复制代码
<div class="box1"></div>
<div class="box2"></div>
复制代码
BFC的总结
- 一切都围绕着【BFC就是页面上的一个隔离的
独立容器
,与外界互不影响
】这句话去解决问题- 浮动子元素令父元素高度坍塌
- 通过令浮动子元素的父元素创建BFC解决问题,因为BFC是独立,与外界互不影响的,那么父元素为了不影响外界的布局,就被浮动子元素撑开了(
BFC计算高度时会包括浮动元素的高度
)
- 通过令浮动子元素的父元素创建BFC解决问题,因为BFC是独立,与外界互不影响的,那么父元素为了不影响外界的布局,就被浮动子元素撑开了(
- 属于同一个BFC的相邻盒子垂直方向的margin合并
- 给任意一个盒子创建BFC,使得这两个盒子属于不同的BFC,它们之间互不影响,这样就不会出现垂直方向的margin合并了(
如果合并了,就是影响了另一个BFC的布局了!
)
- 给任意一个盒子创建BFC,使得这两个盒子属于不同的BFC,它们之间互不影响,这样就不会出现垂直方向的margin合并了(
- 非浮动元素被浮动元素覆盖
- 同理,给非浮动元素创建BFC,使得两者属于不同的BFC,外部的浮动元素和新建的BFC内部的盒子布局互不影响,那么新建的BFC会通过变窄,而不被浮动元素覆盖(两栏自适应布局)
- 浮动子元素令父元素高度坍塌
BFC是独立的容器,与外界互不影响如何理解?
- 一个BFC内部盒子的布局不影响另一个BFC内部盒子的布局(表现为元素不会覆盖,margin不会合并等)
Inline formatting context(IFC)
- IFC由inline-level box的盒子创建,它依然是一块独立的渲染区域,同样规定了IFC内部的盒子是如何布局的
- 而对于IFC,依然需要围绕以下几样东西去探讨它
- 它在
什么条件下会创建
- 它的
布局规则是什么
- 它的
使用场景
(利用它的特性来完成需求)
- 它在
- 而对于IFC,依然需要围绕以下几样东西去探讨它
此处不再赘述,推荐文章:CSS之IFC
Flex formatting context(FFC)
- display属性的值为flex或inline-flex的盒子就会创建FFC,然后内部的盒子按照FFC制定的规则下进行相应的布局(即按照flex布局的相应语法)
- 推荐文章
Grid formatting context(GFC)
- 同理:display属性的值为grid或inline-grid的盒子就会创建GFC,然后内部的盒子按照GFC制定的规则下进行相应的布局
- 推荐文章:
参考
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END