前端知识,什么是BFC?
BFC全称是Block Formatting Context,即块格式化上下文。它是CSS2.1规范定义的,关于CSS渲染定位的一个概念。要明白BFC到底是什么,首先来看看什么是视觉格式化模型。
视觉格式化模型
视觉格式化模型(visual formatting model)是用来处理文档并将它显示在视觉媒体上的机制,它也是CSS中的一个概念。
视觉格式化模型定义了盒(Box)的生成,盒主要包括了块盒、行内盒、匿名盒(没有名字不能被选择器选中的盒)以及一些实验性的盒(未来可能添加到规范中)。盒的类型由display
属性决定。
块盒(block box)
- 当元素的CSS属性
display
为block
,list-item
或table
时,它是块级元素 block-level; - 视觉上呈现为块,竖直排列;
- 块级盒参与(块格式化上下文);
- 每个块级元素至少生成一个块级盒,称为主要块级盒(principal block-level box)。一些元素,比如
<li>
,生成额外的盒来放置项目符号,不过多数元素只生成一个主要块级盒。
行内盒(inline box)
- 当元素的CSS属性
display
的计算值为inline
,inline-block
或inline-table
时,称它为行内级元素; - 视觉上它将内容与其它行内级元素排列为多行;典型的如段落内容,有文本(可以有多种格式譬如着重),或图片,都是行内级元素;
- 行内级元素生成行内级盒(inline-level boxes),参与行内格式化上下文(inline formatting context)。同时参与生成行内格式化上下文的行内级盒称为行内盒(inline boxes)。所有
display:inline
的非替换元素生成的盒是行内盒; - 不参与生成行内格式化上下文的行内级盒称为原子行内级盒(atomic inline-level boxes)。这些盒由可替换行内元素,或
display
值为inline-block
或inline-table
的元素生成,不能拆分成多个盒;
匿名盒(anonymous box)
匿名盒也有分匿名块盒与匿名行内盒,因为匿名盒没有名字,不能利用选择器来选择它们,所以它们的所有属性都为inherit
或初始默认值;
如下面例子,会创键匿名块盒来包含毗邻的行内级盒:
<div>
Some inline text
<p>followed by a paragraph</p>
followed by more inline text.
</div>
三个定位方案
在定位的时候,浏览器就会根据元素的盒类型和上下文对这些元素进行定位。
盒就是定位的基本单位。定位时,有三种定位方案,分别是常规流,浮动已经绝对定位。
常规流(Normal flow)
- 在常规流中,盒一个接着一个排列;
- 在块级格式化上下文里面, 它们竖着排列;
- 在行内格式化上下文里面, 它们横着排列;
- 当
position
为static
或relative
,并且float
为none
时会触发常规流; - 对于静态定位(static positioning),
position: static
,盒的位置是常规流布局里的位置; - 对于相对定位(relative positioning),
position: relative
,盒偏移位置由这些属性定义top
,bottom
,left
andright
。即使有偏移,仍然保留原有的位置,其它常规流不能占用这个位置。
浮动(Floats)
- 盒称为浮动盒(floating boxes);
- 它位于当前行的开头或末尾;
- 这导致常规流环绕在它的周边,除非设置 clear 属性;
绝对定位(Absolute positioning)
- 绝对定位方案,盒从常规流中被移除,不影响常规流的布局;
- 它的定位相对于它的包含块,相关CSS属性:
top
,bottom
,left
及right
; - 如果元素的属性
position
为absolute
或fixed
,它是绝对定位元素; - 对于
position: absolute
,元素定位将相对于最近的一个relative
、fixed
或absolute
的父元素,如果没有则相对于body
;
块格式化上下文
到这里,已经对CSS的定位有一定的了解了,从上面的信息中也可以得知,块格式上下文是页面CSS 视觉渲染的一部分,用于决定块盒子的布局及浮动相互影响范围的一个区域。
BFC的创建方法
- 根元素或其它包含它的元素;
- 浮动 (元素的
float
不为none
); - 绝对定位元素 (元素的
position
为absolute
或fixed
); - 行内块
inline-blocks
(元素的display: inline-block
); - 表格单元格(元素的
display: table-cell
,HTML表格单元格默认属性); overflow
的值不为visible
的元素;- 弹性盒 flex boxes (元素的
display: flex
或inline-flex
);
但其中,最常见的就是overflow:hidden
、float:left/right
、position:absolute
。也就是说,每次看到这些属性的时候,就代表了该元素以及创建了一个BFC了。
BFC的范围
先看一段代码
<div id='div_1' class='BFC'>
<div id='div_2'>
<div id='div_3'></div>
<div id='div_4'></div>
</div>
<div id='div_5' class='BFC'>
<div id='div_6'></div>
<div id='div_7'></div>
</div>
</div>
这段代码表示,#div_1
创建了一个块格式上下文,这个上下文包括了#div_2
、#div_3
、#div_4
、#div_5
。即#div_2
中的子元素也属于#div_1
所创建的BFC。但由于#div_5
创建了新的BFC,所以#div_6
和#div_7
就被排除在外层的BFC之外。
这从另一方角度说明,一个元素不能同时存在于两个BFC中。
BFC的效果
就如刚才提到的,BFC的最显著的效果就是建立一个隔离的空间,断绝空间内外元素间相互的作用。然而,BFC还有更多的特性。
简单归纳一下:
- 内部的盒会在垂直方向一个接一个排列(可以看作BFC中有一个的常规流);
- 处于同一个BFC中的元素相互影响,可能会发生margin collapse;
- 每个元素的margin box的左边,与容器块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此;
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然;
- 计算BFC的高度时,考虑BFC所包含的所有元素,连浮动元素也参与计算;
- 浮动盒区域不叠加到BFC上;
这么多性质有点难以理解,但可以作如下推理来帮助理解:html的根元素就是<html>
,而根元素会创建一个BFC,创建一个新的BFC时就相当于在这个元素内部创建一个新的<html>
,子元素的定位就如同在一个新<html>
页面中那样,而这个新旧html页面之间时不会相互影响的。
上述这个理解并不是最准确的理解,甚至是将因果倒置了(因为html是根元素,因此才会有BFC的特性,而不是BFC有html的特性),但这样的推理可以帮助理解BFC这个概念。
从实际代码来分析BFC
以上花里胡哨一顿说,比较难理解,下面通过一些例子来加深对BFC的认识吧~
实例一
<style>
* {
margin: 0;
padding: 0;
}
.left{
background: #73DE80; /* 绿色 */
opacity: 0.5;
border: 3px solid #F31264;
width: 200px;
height: 200px;
float: left;
}
.right{ /* 粉色 */
background: #EF5BE2;
opacity: 0.5;
border: 3px solid #F31264;
width:400px;
min-height: 100px;
}
.box{
background:#888;
height: 100%;
margin-left: 50px;
}
</style>
<div class='box'>
<div class='left'> </div>
<div class='right'> </div>
</div>
显示效果如下
绿色框('#left')向左浮动,它创建了一个新BFC,但暂时不讨论它所创建的BFC。由于绿色框浮动了,它脱离了原本normal flow的位置,因此,粉色框('#right')就被定位到灰色父元素的左上角(特性3:元素左边与容器左边相接触),与浮动绿色框发生了重叠。
同时,由于灰色框('#box')并没有创建BFC,因此在计算高度的时候,并没有考虑绿色框的区域(特性6:浮动区域不叠加到BFC区域上),发生了高度坍塌,这也是常见问题之一。
实例二
现在通过设置overflow:hidden
来创建BFC,再看看效果如何。
.BFC{
overflow: hidden;
} <div class='box BFC'>
<div class='left'> </div>
<div class='right'> </div>
</div>
灰色框创建了一个新的BFC后,高度发生了变化,计算高度时它将绿色框区域也考虑进去了(特性5:计算BFC的高度时,浮动元素也参与计算);
绿色框和红色框的显示效果仍然没有任何变化。
实例三
<style>
.little{
background: #fff;
width: 50px;
height: 50px;
margin: 10px;
float: left;
}
</style> <div class='box BFC'>
<div class='left'> </div>
<div class='right'>
<div class='little'></div>
<div class='little'></div>
<div class='little'></div>
</div>
</div>
由于粉色框没有创建新的BFC,因此粉色框中白色块受到了绿色框的影响,被挤到了右边去了。先不管这个,看看白色块的margin。
实例四
利用同实例二中一样的方法,为粉色框创建BFC:
<div class='box BFC'>
<div class='left'> </div>
<div class='right BFC'>
<div class='little'></div>
<div class='little'></div>
<div class='little'></div>
</div>
</div>
一旦粉色框创建了新的BFC以后,粉色框就不与绿色浮动框发生重叠了,同时内部的白色块处于隔离的空间(特性4:BFC就是页面上的一个隔离的独立容器),白色块也不会受到绿色浮动框的挤压。
总结
以上就是BFC的分析,BFC的概念比较抽象,但通过实例分析应该能够更好地理解BFC。
在实际中,利用BFC可以闭合浮动(实例二),防止与浮动元素重叠(实例四)。
同时,由于BFC的隔离作用,可以利用BFC包含一个元素,防止这个元素与BFC外的元素发生margin collapse。
前端知识,什么是BFC?的更多相关文章
- 从输入URL到页面加载的过程?如何由一道题完善自己的前端知识体系!
前言 见解有限,如有描述不当之处,请帮忙指出,如有错误,会及时修正. 为什么要梳理这篇文章? 最近恰好被问到这方面的问题,尝试整理后发现,这道题的覆盖面可以非常广,很适合作为一道承载知识体系的题目. ...
- (转)web前端知识精简
Web前端技术由 html.css 和 javascript 三大部分构成,是一个庞大而复杂的技术体系,其复杂程度不低于任何一门后端语言.而我们在学习它的时候往往是先从某一个点切入,然后不断地接触和学 ...
- Web前端知识体系
看到一篇不错的文章,拿来收藏和分享. 原文:http://mp.weixin.qq.com/s/UFTfdE7LYhHquWEzwZKLCQ Web前端技术由html.css和 javascript三 ...
- 资深阿里程序员一一为你解刨Web前端知识体系结构,付出与收获成正比!
只要接触过前端,都会指导web前端的知识主要由三部分组成:分别为静态html,样式css,动态javascript(简称js)这三大部分组成.其三部分组成的一个体系的复杂程度不亚于其他一门技术的复杂程 ...
- 移动端 Web 开发前端知识整理
文章来源: http://www.restran.net/2015/05/14/mobile-web-front-end-collections/ 最近整理的移动端 Web 开发前端知识,不定期更新. ...
- web前端知识体系总结
1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...
- 3 HTML&JS等前端知识系列之javascript的基础
preface 作为一名运维开发,必须懂得前端知识,比如javascript,dom等等,下面就聊聊javascript. include 数据格式 条件判断,循环流程等. 函数 面向对象 what ...
- 自己总结的web前端知识体系大全【欢迎补充】
1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...
- WEB前端知识体系脑图
说在开始的话: 我上大学那会,虽说主要是学Java语言,但是web前端也稍微学了一些,那时候对前端也没多在意,因为涉入的不深,可以搞一个差不多可以看的界面就可以了,其他也没过多在意. 因为稍微了解一点 ...
- Web前端知识技能大汇总
项目起源 还记得@jayli 的这幅前端知识结构图么. 图片的形式具有诸多的不便.缺失源图的我们,无法为此图贡献些什么,随着时间的迁移,或许有些技术点会发生改变,所以有了这个GitHub项目.我们可以 ...
随机推荐
- 通用 Makefile(及makefile中的notdir,wildcard和patsubst)
notdir,wildcard和patsubst是makefile中几个有用的函数,以前没留意过makefile中函数的用法,今天稍微看看~ 1.makefile里的函数 makefile里的函数使用 ...
- C#笔记2__Char类、String类、StringBuilder类 / 正则表达式 /
Char类 String类 字符串的格式化:String类的Format方法 StringBuilder类 以上:百度 or 查手册.....
- filter tools
// 过滤商品分类 Vue.filter("cateFilter", (data) => { let tmp = ["一级分类", "二级分 ...
- 算法学习->求解三角形最小路径
00 问题 00-1 描述 对给定高度为n的一个整数三角形,找出从顶部到底部的最小路径和.每个整数只能向下移动到与之相邻的整数. 找到一个一样的力扣题:120. 三角形最小路径和 - 力扣(LeetC ...
- Eclipse 中的Maven常见报错及解决方法
1.不小心将项目中的Maven Dependencies删除报错 项目报错: 点击Add Library,添加Maven Managed Dependencies又提示如下: 在这个时候需要项目右键: ...
- C 数组类型语法总结
数组类型语法总结 数组指针 和 指针数组 区分 数组指针是一个指针,只对应类型的数组.指针数组是一个数组,其中每个元素都是指针 数组指针遵循指针运算法则.指针数组拥有c语言数组的各种特性 数组类型重命 ...
- 【Python+postman接口自动化测试】(7)Postman 的使用教程
Postman v6的使用 Postman: 简单方便的接口调试工具,便于分享和协作.具有接口调试,接口集管理,环境配置,参数化,断言,批量执行,录制接口,Mock Server, 接口文档,接口监控 ...
- js事件常用操作、事件流
注册事件 给元素添加事件,称为注册事件或者绑定事件. 注册事件有两种方式:传统方式和方法监听注册方式 传统方式 on开头的事件,例如onclick <button onclick="a ...
- Swift-Framework Error(一)桥接文件
摘要 Xcode 编译工程代码时,出现编译错误时除了红色图标外,还会附送几句英文文本. 常规操作拷贝英文文本,放到搜索框中找答案,但是读懂这几句话能事半功倍. 项目中如果有 OC 和 Swift 两种 ...
- CrawlSpider_获取图片名称地址,及入库
1.继承自scrapy.Spider 2.独门秘笈 CrawlSpider可以定义规则,再解析html内容的时候,可以根据链接规则提取出指定的链接,然后再向这些链接发送请求 所以,如果有需要跟进链接的 ...