前端基础系列CSS篇你知道BFC是

BFC是前端面试中经常会被问到的一个知识点,今天就来带大家深入了解下什么是BFC以及它的作用。

文档流

在介绍BFC之前,需要先给大家介绍一下文档流。

我们常说的文档流其实分为定位流、浮动流、普通流三种。

绝对定位(Absolutepositioning)

如果元素的属性position为absolute或fixed,它就是一个绝对定位元素。

在绝对定位布局中,元素会整体脱离普通流,因此绝对定位元素不会对其兄弟元素造成影响,而元素具体的位置由绝对定位的坐标决定。

它的定位相对于它的包含块,相关CSS属性:top、bottom、left、right;

对于position:absolute,元素定位将相对于上级元素中最近的一个relative、fixed、absolute,如果没有则相对于body;

对于position:fixed,正常来说是相对于浏览器窗口定位的,但是当元素祖先的transform属性非none时,会相对于该祖先进行定位。

浮动(float)

在浮动布局中,元素首先按照普通流的位置出现,然后根据浮动的方向尽可能地向左边或右边偏移,其效果与印刷排版中的文本环绕相似。

普通流(normalflow)

普通流其实就是指BFC中的FC。FC(FormattingContext),直译过来是格式化上下文,它是页面中的一块渲染区域,有一套渲染规则,决定了其子元素如何布局,以及和其他元素之间的关系和作用。

在普通流中,元素按照其在HTML中的先后位置至上而下布局,在这个过程中,行内元素水平排列,直到当行被占满然后换行。块级元素则会被渲染为完整的一个新行。

除非另外指定,否则所有元素默认都是普通流定位,也可以说,普通流中元素的位置由该元素在HTML文档中的位置决定。

BFC概念

先看下MDN上关于BFC的定义:

块格式化上下文(BlockFormattingContext,BFC)是Web页面的可视CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。

具有BFC特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且BFC具有普通容器所没有的一些特性。

通俗一点来讲,可以把BFC理解为一个封闭的大箱子,箱子内部的元素无论如何翻江倒海,都不会影响到外部。

除了BFC,还有:

IFC(行级格式化上下文)-inline内联GFC(网格布局格式化上下文)-display:gridFFC(自适应格式化上下文)-display:flex或display:inline-flex

注意:同一个元素不能同时存在于两个BFC中。

BFC的触发方式

MDN上对于BFC的触发条件写的很多,总结一下常见的触发方式有(只需要满足一个条件即可触发BFC的特性):

根元素,即html浮动元素:float值为left、rightoverflow值不为visible,即为auto、scroll、hiddendisplay值为inline-block、table-cell、table-caption、table、inline-table、flex、inline-flex、grid、inline-grid绝对定位元素:position值为absolute、fixedBFC的特性BFC是页面上的一个独立容器,容器里面的子元素不会影响外面的元素。BFC内部的块级盒会在垂直方向上一个接一个排列同一BFC下的相邻块级元素可能发生外边距折叠,创建新的BFC可以避免外边距折叠每个元素的外边距盒(marginbox)的左边与包含块边框盒(borderbox)的左边相接触(从右向左的格式的话,则相反),即使存在浮动浮动盒的区域不会和BFC重叠计算BFC的高度时,浮动元素也会参与计算应用

BFC是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然。我们可以利用BFC的这个特性来做很多事。

自适应两列布局

左列浮动(定宽或不定宽都可以),给右列开启BFC。

divdivclass="left"浮动元素,无固定宽度/divdivclass="right"自适应/div/div

*{margin:0;padding:0;}.left{float:left;height:px;margin-right:10px;background-color:red;}.right{overflow:hidden;height:px;background-color:yellow;}

效果:

将左列设为左浮动,将自身高度塌陷,使得其它块级元素可以和它占据同一行的位置。右列为div块级元素,利用其自身的流特性占满整行。右列设置overflow:hidden,触发BFC特性,使其自身与左列的浮动元素隔离开,不占满整行。

这即是上面说的BFC的特性之一:浮动盒的区域不会和BFC重叠

防止外边距(margin)重叠

兄弟元素之间的外边距重叠

divdivclass="child1"/divdivclass="child2"/div/div

*{margin:0;padding:0;}.child1{width:px;height:px;margin-bottom:10px;background-color:red;}.child2{width:px;height:px;margin-top:20px;background-color:green;}

效果:

两个块级元素,红色div距离底部10px,绿色div距离顶部20px,按道理应该两个块级元素相距30px才对,但实际却是取距离较大的一个,即20px。

块级元素的上外边距和下外边距有时会合并(或折叠)为一个外边距,其大小取其中的较大者,这种行为称为外边距折叠(重叠),注意这个是发生在属于同一BFC下的块级元素之间

根据BFC特性,创建一个新的BFC就不会发生margin折叠了。比如我们在他们两个div外层再包裹一层容器,加属性overflow:hidden,触发BFC,那么两个div就不属于同个BFC了。

divdivclass="parent"divclass="child1"/div/divdivclass="parent"divclass="child2"/div/div/div

.parent{overflow:hidden;}/*...*/

这个关于兄弟元素外边距叠加的问题,除了触发BFC也有其他方案,比如你统一只用上边距或下边距,就不会有上面的问题。

父子元素的外边距重叠

这种情况存在父元素与其第一个或最后一个子元素之间(嵌套元素)。

如果在父元素与其第一个/最后一个子元素之间不存在边框、内边距、行内内容,也没有创建块格式化上下文、或者清除浮动将两者的外边距分开,此时子元素的外边距会“溢出”到父元素的外面。

divid="parent"divid="child"/div/div

*{margin:0;padding:0;}#parent{width:px;height:px;background-color:green;margin-top:20px;}#child{width:px;height:px;background-color:red;margin-top:30px;}

如上图,红色的div在绿色的div内部,且设置了margin-top为30px,但我们发现红色div的顶部与绿色div顶部重合,并没有距离顶部30px,而是溢出到父元素的外面计算。即本来父元素距离顶部只有20px,被子元素溢出影响,外边距重叠,取较大的值,则距离顶部30px。

解决办法:

给父元素触发BFC(如添加overflow:hidden)给父元素添加border给父元素添加padding

这样就能实现我们期望的效果了:

清除浮动解决令父元素高度坍塌的问题

当容器内子元素设置浮动时,脱离了文档流,容器中总父元素高度只有边框部分高度。

divclass="parent"divclass="child"/div/div

*{margin:0;padding:0;}.parent{border:4pxsolidred;}.child{float:left;width:px;height:px;background-color:blue;}

解决办法:给父元素触发BFC,使其有BFC特性:计算BFC的高度时,浮动元素也会参与计算

.parent{overflow:hidden;border:4pxsolidred;}

上面我们都是用的overflow:hidden触发BFC,因为确实常用,但是触发BFC也不止是只有这一种方法。

如上面写的所示,可以设置float:left;,float:right;,display:inline-block;,overflow:auto;,display:flex;,display:table;,position为absolute或fixed等等,这些都可以触发,不过父元素宽度表现不一定相同,但父元素高度都被撑出来了。

当然实际运用可不是随便挑一个走,还是根据场景选择。

最后

《前端面试题宝典》经过近一年的迭代,现已推出小程序和电脑版刷题网站(


转载请注明:http://www.aierlanlan.com/grrz/334.html