CSS中有一个重要的概念BFC。理解BFC可以帮助我们理解CSS中一些原始怪异(??)的地方。一、简介在讲解BFC之前,先说说文档流。我们常说的文档流其实分为定位流、浮动流、普通流三种。普通流其实是指BFC中的FC。FC(FormattingContext),直译为FormattingContext,是页面中的一个渲染区域,有一套渲染规则,决定了它的子元素如何布局,以及与其他元素的关系和作用。常见的FC包括BFC、IFC、GFC和FFC。BFC(BlockFormattingContext)块级格式化上下文是用来布局块级框的渲染区域。MDN上的解释:BFC是网页CSS可视化渲染的一部分,用于确定块状框的布局和浮动交互范围的区域。注意:BFC的范围包括创建上下文元素的所有子元素,但不包括创建新BFC的子元素的内部元素。这从另一个角度说明了一个元素不能同时存在于两个BFC中。因为如果一个元素可以同时在两个BFC中,就意味着这个元素可以和两个BFC中的元素进行交互,违反了BFC的隔离功能。2.文档流的三种定位方案正常流正常流中,框一个一个排列;在块级格式化上下文中,它们是垂直排列的;在行内格式化上下文中,它们是水平排列的;当position为static或relative,且float为none时,会触发regularflow;对于静态定位(staticpositioning),position:static,盒子的位置就是常规流布局中的位置;对于相对定位(relativepositioning),position:Relative,框偏移位置由top,bottom,left,right属性定义。即使有偏移,原来的位置还是保留的,其他常规流不能占据这个位置。浮动(Floats)左浮动的元素应该尽可能靠近左边和顶部,右浮动也是一样的,这会导致正常的流环绕它,除非设置了clear属性。浮动元素不会影响块级元素的布局,但是浮动元素会影响内联元素的布局。布局,让它包围自己,展开父元素,间接影响块级元素布局的最高点不会超过当前行的最高点,前面浮动元素的最高点也不会超出其包含块,除非该元素内联元素已经比包含块宽。内联元素出现在左浮动元素的右侧和右浮动元素的左侧。左浮动元素的左侧和右浮动元素的右侧是绝对定位,不会放置浮动元素(绝对定位)绝对定位解决方案,将盒子从正常流中移除,不影响布局正常流量;它的定位是相对于它的包含块,相关的CSS属性:top,bottom,left,right;如果元素的属性position是absolute或者fixed,则为绝对定位元素;对于position:absolute,元素定位会相对于父元素中最近的relative,fixed,absolute,如果没有则相对于body;3、BFC触发方法的根元素,即HTML标签的浮动元素:float值为left,rightoverflow值为不可见,值为auto,scroll,hiddendisplay值为inline-block,table-cell,table-caption,table,inline-table,flex,inline-flex,grid,inline-grid定位元素:位置值是绝对的,固定的注意:之所以display:table也能生成BFC是因为Table会生成一个匿名的默认情况下是table-cell,这个匿名table-cell生成BFC。4.约束规则浏览器对BFC区域的约束规则:生成的BFC元素的子元素会被一一放置。垂直方向它们的原点是包含块的顶部,两个相邻子元素之间的垂直距离取决于元素的边距属性。BFC中相邻块级元素的外边距会塌陷(Masteringmargincollapsing)。在生成的BFC元素的子元素中,每个子元素的左边距触及包含块的左边界(对于从右到左的格式,右边距触及右边界),即使是浮动元素(尽管由于浮动,子元素将被压缩),除非该子元素也创建了一个新的BFC(例如,它本身就是一个浮动元素)。规则解读:内部的Boxes会在垂直方向上依次放置。内部Boxes的垂直距离由边距决定。(完整的说法是:属于同一个BFC的两个相邻Boxes的外边距会塌陷,不同的BFC不会塌陷。)每个元素的左外边距触及包含块的左边界(从左到右),甚至对于浮动元素。(这意味着BFC中的子元素不会超出其包含块,position为absolute的元素可以超出其包含块的边界。)BFC的区域不会与的元素区域重叠漂浮。在计算BFC的高度时,浮动的子元素也会参与计算5.功能BFC在页面上是一个隔离独立的容器,容器里面的子元素不会影响外面的元素,反之亦然。我们可以利用BFC的这个特性来做很多事情。5.1防止元素被浮动元素覆盖正常文档流中的块元素可能会被浮动元素覆盖,排挤正常文档流,所以可以通过设置元素的浮动、显示、位置值等来触发BFC防止它被浮动框覆盖。使用BFC防止元素被浮动元素覆盖5.2可以包含浮动元素通过改变包含浮动子元素的父框的属性值,触发BFC包含子元素的浮动框。使用BFC来包含浮动元素注意这里触发BFC并不会阻止其他形式的流外元素覆盖正常流元素。BFC内部的其他表单不在文档流外(绝对固定)5.3防止多列布局因浏览器四舍五入而中断。在最后一列触发BFC以防止发生换行的表单。比如下面栗子的特例,使用BFC来防止多列布局的最后一列换行。5.4防止相邻元素的margin合并,属于同一个BFC的两个相邻的块级子元素的上下margin会重叠。(设置书写模式:tb-rl,水平边距重叠)。因此,当两个相邻的块级子元素属于不同的BFC时,可以防止边距重叠。在这里,一个div包裹着任何相邻的块级框,通过改变这个div的属性,将原来的两个框分属于两个不同的BFC,从而防止边距重叠。使用BFC来防止margin合并,但是这里有一个问题:如果外面有一层div,设置任何可以触发BFC的属性都可以防止相邻元素的margin合并。不会发生边际合并,因为它们属于不同的BFC。而如果一个div没有被包裹在外面,将display设置为inline-block、inline-flex、table-captain、position设置为absolute、fixed、floattoleftandright可以防止边距合并。问题来了:我们知道设置position和float会导致元素脱离文档流而创建新的BFC,所以这两个元素不是相邻元素,所以可以防止相邻元素的边距合并,但是inline-block,inline-flex,inline-grid,table-captain为什么可以工作呢?如果有人知道为什么,请告诉我~网上的帖子大多深度不一,甚至有些不一致。以下文章是学习过程中的总结。如有发现错误,请留言指出~参考:我对BFC的理解深入理解BFC深入理解BFCUnderstandingBlockFormattingContextsinCSSwithMarginCollapseLearningBFCPS:欢迎大家关注我公众号【前端下午茶】,一起努力吧~另外可以加入“前端下午茶交流群”微信群,长按识别以下两位可以加我为好友二维码,加群备注,我拉你进群~
