BFC
BFC
全称 Block Formatting Context,翻译过来就是块格式化上下文,它是 CSS 规范的一部分。
可以用一些 CSS 属性为一个元素创建出 BFC。决定元素的内容如何渲染以及与其他元素的关系和交互。BFC 有一个重要的特点:具有隔离作用。
通过下列方式可以创建块格式化上下文:
- 根元素
;
- 浮动(
float
,但值不能是none
); - 绝对定位元素(
position
为absolute
或者fixed
); overflow
值不为visible
的块元素;display
值为flow-root
的元素;- 行内块元素(
display
为inline-block
); display
为flow-root
,它可以创建无副作用的 BFC;- 弹性元素(
display
为flex
或inline-flex
元素的直接子元素); - 网格元素(
display
为grid
或inline-grid
元素的直接子元素`); - 多列容器(元素的
column-count
或column-width
不为auto
); - 表格单元格(
display
为table-cell
,HTML 表格单元格默认为该值); - 表格标题(
display
为table-caption
,HTML 表格标题默认为该值); - 匿名的表格单元格元素(元素的
display
为table
、table-row
、inline-table
等);
两个典型的例子:
- 如何让浮动内容和周围的内容等高?
- 如何解决 margin 塌陷?
让浮动内容和周围的内容等高
比如下面的代码:
<style>#main{background-color: gold;
}.child1{height: 200px;width: 100px;float: left;background-color: green;
}style>
<div id="main">
<div class="child1">div>
div>
child1
使用了 float
,浮动脱离了文档流,child1
创建了 BFC。而 #main
元素没有设置确切的高度,也没有创建 BFC,就造成了高度的塌缩。
要解决这个问题可以给 #main
元素也创建 BFC,创建方式有很多种,比如 display: flow-root
或者 overflow: hidden
。
#main{
background-color: gold;
overflow: hidden;
}
解决 margin 塌陷
例如:
<style>#main{height: 200px;width: 200px;margin-top: 100px;background-color: gold;
}.child1{margin-top: 50px;height: 100px;width: 100px;background-color: green;
}style>
<div id="main">
<div class="child1">div>
div>
结果就发现,只有父元素的 margin 生效了,解决这个问题是给 #main
元素创建 BFC,让子元素与外部元素隔离。
#main{
height: 200px;
width: 200px;
margin-top: 100px;
background-color: gold;
overflow: hidden;
}
结论:处于同一个 BFC 中的元素相互影响,可能会发生 margin 塌陷。 一开始 #main
元素和他的子元素 child1
都不具备 BFC,都处于根元素的 BFC 中,也就产生了影响。#main
元素创建 BFC 后,内部的子元素就与外部做了隔离。
clear 属性
利用浮动可以创建出基本的页面布局,也可以实现文字环绕效果,例如:
<style>#main{border: 1px solid red;overflow: hidden;
}p{margin: 0;
}.child1{width: 100px;height: 100px;background-color: rgba(20, 100, 0, .6);float: left;
}style>
<div id="main">
<div class="child1">div>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ullam fugiat, incidunt culpa voluptates commodi soluta, cupiditate sequi corporis atque nihil provident magni quos veritatis, dolorem velit temporibus autem pariatur earum?p>
div>
效果:
但有时候浮动会影响到周围元素,尤其是把周围元素遮盖住,这是我们不希望看到的。
CSS 提供了 clear
属性可以给一个元素清除浮动。例如下面的代码:
<style>#main{border: 1px solid red;overflow: hidden;
}.child1{width: 100px;height: 30px;background-color: gold;float: left;
}.child2{width: 100px;height: 30px;background-color: green;
}.middle{width: 200px;height: 30px;background-color: purple;
}style>
<div id="main">
<div class="child1">div>
<div class="middle">div>
<div class="child2">div>
div>
当 child1
左浮动后,middle
就会被遮挡。
要想完整显示 middle
的内容可以使用 clear: left
,表示清除左边的浮动,这样它会移动到浮动元素的下方。
.middle{
clear: left;
}
clear
属性不仅可以应用于非浮动块,也可以应用于浮动块。例如下面的代码,假如 child1
和 child2
都是浮动元素,并且 child1 是左浮动,child2 是右浮动。如果给 child2 加入 clear: left
,那么 child2 的上边框会与 child1 的下边框对齐。
<div class="wrapper">
<div class="child1">div>
<div class="child2">div>
div>
假设 wrapper
元素没有固定的高度,那么高度就会塌缩。
如果想要 wrapper
自适应即包含所有浮动元素,那就需要清除浮动或者给 wrapper
元素创建 BFC。清除浮动可以这么做:
.wrapper::after {
content: "";
display: block;
clear: both;
}
总结
BFC 即:格式化上下文,它既不是一个 CSS 属性,也不是一段代码,而是 CSS2.1 规范中的一个概念,决定元素的内容如何渲染以及与其他元素的关系和交互。BFC 有五条规则:
- BFC 有隔离作用,内部元素不会受外部元素的影响(反之亦然)。
- 一个元素只能存在于一个 BFC 中,如果能同时存在于两个 BFC 中,那么就违反了 BFC 的隔离规则。
- BFC 内的元素按正常流排列,元素之间的间隙由元素的外边距(margin)控制。
- BFC 中的内容不会与外面的浮动元素重叠。
- 计算 BFC 的高度,需要包括 BFC 内的浮动子元素的高度。
选择器权重
类型 | 例子 | 权重 |
---|---|---|
ID 选择器 | #root | 100 |
class 选择器 | .wrapper | 10 |
属性选择器 | [type='text'] | 10 |
标签和伪类 | div | 1 |
伪元素 | ::first-letter | 1 |
行内样式 |
| 1000 |
通配符 | * | 0 |
关系选择符(+
、>
、``、||
、~
)与通配符一样,都是没有权重的。
如果一个样式属性后面加上 !important
规则,此声明将覆盖任何其他声明。也可以认为它的优先级是最高的。
继承和通配符
例如下面的代码:
<style>
*{color: red;
}p{color: green;
}style>
<p>OK!!!
<span>span spanspan>
p>
问 span
元素的字体颜色是什么颜色?
答案是 red
,这说明通配符的权重要比继承权重大。如果去掉通配符,那么 span
的字体颜色将继承 p
元素的字体颜色。
关系选择器
- 在下列关系选择器中,找出相邻选择器,能匹配相邻兄弟元素的是?
A. .bfc+div
B. .bfc div
C. .bfc > div
D. .bfc~div
答案是 A
第二个选项表示后代选择器,儿子元素、孙子元素都可以选择到;
第三个选项表示子代选择器,只有 .bfc 的子元素可以选择到;
第四个选项表示通用的兄弟选择器,不管相不相邻都可以选择到;
- 以下属性选择器表示属性值以“val-”开头的是?
A. [attr^="val"]
B. [attr~="val"]
C. [attr|="val"]
D. [attr$="val"]
答案 C
属性选择器通过已经存在的属性名或属性值匹配元素。例如:
input[type="text"]{
color: red;
}
[attr^="val"]
表示属性值以val
开头,题目是说以val-
开头,所以不正确;[attr~="val"]
表示属性值用空格分割为多个值,其中至少有一个值是val
,例如class
属性就可以有多个值;[attr|="val"]
表示带有以attr
命名的属性的元素,属性值为val
或以val-
为前缀。选取有自定义属性的元素时可以使用该选择器(data-*
)。[attr$="val"]
表示属性值以字符串val
结尾;[attr*="val"]
表示选取 attr 属性值中包含val
字符串的元素。
除此之外,还有一种格式:
[attr operator value i]
它表示在属性选择器的右方括号前添加一个用空格隔开的字母 i(或 I,大小写不敏感),可以在匹配属性值时忽略大小写。如:
/* 包含 "insensitive" 的链接,不区分大小写 */
a[href*="insensitive" i] {
color: cyan;
}
/* 包含 "cAsE" 的链接,区分大小写 */
a[href*="cAsE" s] {
color: pink;
}
参考资料:
视觉化模型:
https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Visual_formatting_model