BFC是耳熟能详的一个东西了,常常听到,其实在项目中也常常用到,好比最经常使用的清除浮动,自适应两栏布局等等。只是都没有去深究其原理和相关的知识点,今天就一块儿来好好学习一下吧。css
要明白BFC
是什么,咱们要先来了解几个相关的概念。html
MDN对其描述以下:前端
当对一个文档进行布局(lay out)的时候,浏览器的渲染引擎会根据标准之一的CSS基础盒模型(CSS basic box model)
,将全部元素表示为一个个矩形的盒子(box)。CSS决定这些盒子的大小、位置和以及属性(例如颜色、背景、边框尺寸...)。css3
每一个盒子由四个部分(或称区域)组成,其效用由它们各自的边界(Edge)所定义(原文:defined by their respective edges,可能意指容纳、包含、限制等)。如图,与盒子的四个组成区域相对应,每一个盒子有四个边界:内容边界 Content edge、内边距边界 Padding Edge、边框边界 Border Edge、外边框边界 Margin Edge。浏览器
咱们在浏览器的控制台也能够很清楚的看到页面的每个元素(除了单独的文本元素),其实都是一个盒子:安全
更加详细的介绍能够参考MDN或者W3C规范的描述:bash
MDN 对其描述以下:布局
CSS视觉格式化模型(visual formatting model)是用来处理和在视觉媒体上显示文档时使用的计算规则。该模型是CSS的基础概念之一。post
视觉格式化模型会根据CSS盒子模型
将文档中的元素转换为一个个盒子,每一个盒子的布局由如下因素决定:
关于不一样类型盒子的介绍,你们能够直接看MDN,写的很详细了,这里就再也不阐述。这边着重讲下定位方案。
一旦生成了盒子,CSS引擎就须要定位它们以完成布局。在定位的时候,浏览器会根据元素的盒类型和上下文对这些元素进行定位,能够说盒就是定位的基本单位。定位时有三种定位方案,分别是:常规流(即普通流)、浮动流以及绝对定位。
position
为static
或relative
,而且float
为none
时,会触发常规流position: static
,盒的位置是常规流布局里的位置;position: relative
,盒偏移位置右这些属性定义:top
、bottom
、left
、right
。即便有偏移,仍然保留原有的位置,其余常规流不能占用这个位置。clear
属性;top
、bottom
、left
、right
;position: absolute
,元素定位相对于最近的一个relative
、absolute
或fixed
的父元素,若是没有则相对于body
Formatting context是W3C CSS2.1规范中的一个概念。它是页面中一块渲染区域,而且有一套渲染规则,它决定了其子元素将如何定位,以及和其余元素的关系和相互做用。最多见的Formatting context有Block formatting context(简称BFC)和Inline formatting context(简称IFC)。
CSS2.1中只有BFC
和IFC
,CSS3中还增长了GFC
和FFC
。咱们主要来说下BFC
。
好了,接下来轮到咱们的主角BFC
出场了。
BFC
(Block Formatting Context)直译为块级格式化上下文。它是一个独立的渲染区域,只有Box-level box参与,它规定了内部的Block-level box如何布局,而且与这个区域外部绝不相干。
讲了这么多概念,说下本身的理解,若是有不对的地方,烦请指出,感激涕零。
CSS的盒模型
将全部元素表示为一个个盒子;视觉格式化模型
来定义的,盒子的类型能够分为:行内盒子(inline)、行内级盒子(inine level)、原子行内级盒子(atomic inine-level)、块盒子(block);是否是能够这样理解:BFC
就是普通流中的元素布局定位时的一个执行环境?
writing-mode
属性。)margin
决定。属于同一个BFC
的两个相邻Box的margin
会发生重叠BFC
的区域不会与float box重叠BFC
就是页面上的一个隔离的独立的容器,容器里面的子元素不会影响到外面的元素,反之亦如此BFC
的高度时,浮动元素也参与计算float
属性值不为none
position
为absolute
或fixed
display
为inline-block
、table-cell
、table-caption
、flex
、inline-flex
overflow
不为visible
其实还有不少,这里列出的是一些比较经常使用的,跟详细的能够看MDN。
实现自适应两栏布局的方法有不少,可是我以为BFC
的方式应该是最简单的了。
<body>
<div class="container">
<div class="side"></div>
<div class="main"></div>
</div>
</body>
复制代码
.container {
width: 400px;
}
.side {
float: left;
width: 100px;
height: 100px;
background: lightpink;
}
.main {
height: 300px;
background: lightblue;
}
复制代码
页面截图:
根据BFC
布局规则第3条:
每一个元素的margin box的左边,与包含快border box的左边相接触(对于从左往右的格式化,不然相反),即便存在浮动也是如此(除非该盒创建了一个新的块格式化上下文)
即便存在浮动元素side
,main
的左边依然会与包含快的左边相接触。
根据BFC
布局规则第4条:
BFC
的区域不会与float box重叠
因此,咱们能够给main
建立一个新的BFC
,这样就不会跟浮动的side
重叠了,它会根据包含块的宽度和side
的宽度,自动变窄。
给main
加上overflow: hidden
main {
overflow: hidden;
}
复制代码
再来看下效果:
<div class="parent">
<div class="child"></div>
</div>
复制代码
.parent {
width: 200px;
border: 2px solid blue;
background: lightblue;
}
.child {
float: left;
width: 100px;
height: 100px;
border: 2px solid red;
background: lightcoral;
}
复制代码
页面截图:
能够看到,因为子元素设置了浮动,而父元素又没有设置高度,致使父元素高度塌陷了:没有自动被子元素的高度撑开。
根据BFC
布局规则第6条:
计算BFC的高度时,浮动元素也参与计算
咱们能够给父元素parent
触发BFC
,那么它在计算高度时,内部的浮动元素也会参与计算。
.parent {
overflow: hidden;
}
复制代码
再看下效果:
<div class="box">box</div>
<div class="box">box</div>
复制代码
.box {
width: 200px;
height: 200px;
margin: 100px;
background: red;
}
复制代码
页面截图:
根据BFC
布局规则第2条:
Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
能够看到,第一个div的下边距跟第二个的上边距发生了重叠。
重叠的结果按照以下规则计算:
产生折叠的必备条件:margin必须是邻接的!
咱们只要给其中一个div外层再包裹一层div,而后触发其生成一个新的BFC
,它们就不会发生重叠了。
<div class="box">box</div>
<div class="new-bfc">
<div class="box">box</div>
</div>
复制代码
.new-bfc {
overflow: hidden;
}
复制代码
页面截图:
还有不少其余的例子,好比能够避免文字环绕、多列布局等等,这里就再也不一一列举,你们有兴趣的能够本身多尝试下,这里有一个网址能够在线演示,更加直观, 连接地址:www.cnblogs.com/xiaohuochai…
咱们上面举的例子都是经过overflow
来建立BFC
,可是其实这个方法会有两个问题。
BFC
时可能会存在一些反作用。例如,使用overflow
建立BFC
后,在某些状况下可能会看到出现一个滚动条或者元素内容被裁切。这是因为overflow
属性的设计是用来让你告诉浏览器如何定义元素的溢出状态的。浏览器执行了它最基本的定义。overflow
也可能会使另外一个开发人员感到困惑。他们可能会各类猜测:这里为何要把overflow
的值设为auto
或hidden
?原来的开发人员这样作的意义是什么?原来的开发人员是想让这里出现滚动条吗?因此实际项目开发中,还须要根据项目的需求来选择合适的方法,最好也能在代码里写明注释。
那有没有什么更好的方式呢?CSS工做组定义了一个新的属性值:display: flow-root
。
你可使用display: flow-root
安全的建立BFC
,来解决上文中提到的各类问题:自适应两栏布局、清除内部浮动、阻止margin重叠等等。
caniuse上display: flow-root
在各浏览器的兼容状况,看图:
目前来看,兼容性仍是差了一点。
有关于
flow-root
的详细介绍能够看这篇文章:www.w3cplus.com/css3/displa…
能够想象一下,BFC
就至关于咱们现实中的一个纸箱(盒子),箱子里面的东西的放置(布局)是不会受到外部其余东西的影响的,它造成了一个独立的封闭的区域。固然它里面东西的放置(布局)也不会影响到外面的东西。
感谢您的阅读,但愿对你有所帮助,但愿你能经过这篇文章能对BFC
有一个比较全面的理解并能实际应用到项目开发中。本人水平有限,若是文中有不当的地方烦请指正,感激涕零。
欢迎你们关注个人公众号前端帮帮忙
,一块儿交流学习,共同进步。
参考: