一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第23天,点击查看活动详情
FC
FC全称为Formatting Context,也就是格式化上下文
在CSS中,任何一个在标准流中的元素都属于一个FC
块级元素的布局属于Block Formatting Context(BFC)
- block level box都是在BFC中布局的
行内级元素的布局属于Inline Formatting Context(IFC)
- inline level box都是在IFC中布局的
- 本质上 行盒就是一个IFC
BFC
block format context(块级格式化上下文) 是页面的一块渲染区域 并且有一套渲染规则,决定了子元素如何定位 以及与其他元素之间的排列 布局之间的关系
BFC是一个独立的布局环境 相当于是一个容器 在其中按照一定的规则对块级元素进行摆放 ,并且不会影响其他的布局环境中的盒子,如果一个元素触发BFC则BFC中的元素布局不受外界的影响
对于位于BFC中的元素,存在如下特点:
- box会在垂直方向上一个挨着一个的排布
- 垂直方向的间距由margin属性决定
- 在同一个BFC中,相邻两个box之间的margin会折叠(collapse)
- 在BFC中,每个元素的左边缘是紧挨着包含块的左边缘的 --- 也就意味着元素默认是左对齐的
- BFC内部元素的布局和外部元素的布局互不影响,相互独立
可以开启BFC的元素
- 根元素(
<html>) - 浮动元素 (元素的 float 不是 none)
- 绝对定位元素 (元素的 position 为 absolute 或 fixed)
- 行内块元素 (元素的 display 为 inline-block)
- 表格相关元素 (table, th, td, tbody, thead, tr, tfooter, captain等)
- overflow 计算值(Computed)不为 visible 的块元素
- 弹性元素(display 为 flex 或 inline-flex 元素的直接子元素)
- 网格元素(display 为 grid 或 inline-grid 元素的直接子元素)
- display 值为 flow-root 的元素
最常用的开启元素BFC的方式是,设置overflow: auto,或者使用display: flow-root
因为使用这2种方式开启元素的BFC,所造成的副作用是最小的
BFC的作用
- 解决margin的折叠问题
在同一个BFC中,相邻两个box之间的margin会折叠(collapse)
所以只要让两个盒子不在同一个BFC中,这两个相邻的盒子之间的margin就不会发生折叠
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 300px;
height: 300px;
}
.container {
/*
注意: BFC是决定其子块级元素的排列方式
所以需要给div.box1的父元素进行开启
不可以直接开启div.box1的BFC
因为此时div.box1内容是一个独立的BFC
但是div.box1本身和div.box2一样都位于同一个BFC中
皆位于由html开启的BFC中
*/
display: flow-root;
}
.box1 {
background-color: red;
margin-bottom: 30px;
}
.box2 {
background-color: blue;
margin-top: 50px;
}
</style>
</head>
<body>
<div class="container">
<div class="box box1"></div>
</div>
<div class="box box2"></div>
</body>
</html>
- 解决浮动高度塌陷问题
使用BFC解决浮动高度塌陷问题有两个前提条件
- 浮动元素的父元素触发BFC,形成独立的块级格式化上下文(Block Formatting Context)
- 浮动元素的父元素的高度是auto的
此时因为开启BFC的元素高度是auto,那么其高度的计算规则如下:
- 如果只有inline-level,是行高的顶部和底部的距离 --- 也就是按照行盒的高度来进行计算
- 如果有block-level,是由最底层的块上边缘和最底层块盒子的下边缘之间的距离 --- 元素的高度 + margin
- 如果有绝对定位元素,将被忽略, 相对定位元素本质上并没有脱标,所以其高度会被计算在内
- 如果有浮动元素,那么
BFC会增加高度以包括这些浮动元素的下边缘--- BFC会自动增加高度以包含所有的浮动元素(包括浮动元素的margin也会被包含在内)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container {
width: 300px;
background-color: skyblue;
display: flow-root;
}
.item {
width: 100px;
height: 100px;
background-color: red;
border: 1px solid blue;
box-sizing: border-box;
float: left;
}
</style>
</head>
<body>
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</body>
</html>
- 阻止元素被浮动元素覆盖
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container {
width: 300px;
height: 300px;
background-color: skyblue;
line-height: 300px;
color: #fff;
text-align: center;
font-size: 30px;
}
.left {
width: 100px;
height: 100%;
float: left;
background-color: gray;
}
.right {
width: calc(100% - 100px);
height: 100%;
background-color: orange;
display: flow-root;
}
</style>
</head>
<body>
<div class="container">
<div class="left">left</div>
<div class="right">right</div>
</div>
</body>
</html>