说起KFC,大家都知道是肯德基??,但面试官问你什么是BFC、IFC、GFC和FFC的时候,你是否能够像回答KFC是肯德基时的迅速,又或者说后面这些你根本就没听说过,作为一名前端开发工程师,以上这些FC(ForrmattingContext)你都得知道,而且必须得做到像肯德基这样印象深刻。下面我将会带大家一起揭开这些FC的真面目,如果你已经了解的请奖励自己一顿肯德基~(注意文明用语,这里别用语气词??)
FC的全称是:FormattingContexts,译作格式化上下文,是W3CCSS2.1规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。
「CSS2.1中只有BFC和IFC,CSS3中才有GFC和FFC。」
前置概念在学习各种「FC」之前,我们先来了解几个基本概念:
Box(CSS布局基本单位)?简单来讲,我们看到的所有页面都是由一个个Box组合而成的,元素的类型和display属性决定了Box的类型。
?「block-levelBox:」当元素的CSS属性display为block,list-item或table时,它是「块级元素」block-level。块级元素(比如p)视觉上呈现为块,竖直排列。每个块级元素至少生成一个块级盒(block-levelBox)参与BFC,称为主要块级盒(principalblock-levelbox)。一些元素,比如li,生成额外的盒来放置项目符号,不过多数元素只生成一个主要块级盒。「Inline-levelBox:」当元素的CSS属性display的计算值为inline,inline-block或inline-table时,称它为「行内级元素」。视觉上它将内容与其它行内级元素排列为多行。典型的如段落内容,有文本或图片,都是行内级元素。行内级元素生成行内级盒(inline-levelboxes),参与行内格式化上下文IFC。「flexcontainer:」当元素的CSS属性display的计算值为flex或inline-flex,称它为「弹性容器」。display:flex这个值会导致一个元素生成一个块级(block-level)弹性容器框。display:inline-flex这个值会导致一个元素生成一个行内级(inline-level)弹性容器框。「gridcontainer:「当元素的CSS属性display的计算值为grid或inline-grid,称它为」栅格容器」。块容器盒(blockcontainerbox)只包含其它块级盒,或生成一个行内格式化上下文(inlineformattingcontext),只包含行内盒的叫做「块容器盒子」。
也就是说,块容器盒要么只包含行内级盒,要么只包含块级盒。
?块级盒(block-levelBox)是描述元素跟它的父元素与兄弟元素之间的表现。
块容器盒(blockcontainerbox)描述元素跟它的后代之间的影响。
?块盒(BLockBoxes)同时是块容器盒的块级盒称为块盒(blockboxes)
行盒(Lineboxes)行盒由行内格式化上下文(inlineformattingcontext)产生的盒,用于表示一行。在块盒里面,行盒从块盒一边排版到另一边。当有浮动时,行盒从左浮动的最右边排版到右浮动的最左边。
OK,了解完上面这些概念,我们再来看我们本篇文章的重点内容(终于要揭开各种FC的庐山真面目了,期待~)
BFC(BlockFormattingContexts)块级格式化上下文什么是BFC?BFC全称:BlockFormattingContext,名为「块级格式化上下文」。
W3C官方解释为:BFC它决定了元素如何对其内容进行定位,以及与其它元素的关系和相互作用,当涉及到可视化布局时,BlockFormattingContext提供了一个环境,HTML在这个环境中按照一定的规则进行布局。
如何触发BFC?根元素或其它包含它的元素
浮动float:left/right/inherit
绝对定位元素position:absolute/fixed
行内块display:inline-block
表格单元格display:table-cell
表格标题display:table-caption
溢出元素overflow:hidden/scroll/auto/inherit
弹性盒子display:flex/inline-flex
BFC布局规则内部的Box会在垂直方向,一个接一个地放置。
Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。
每个元素的marginbox的左边,与包含块borderbox的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
BFC的区域不会与floatbox重叠。
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
计算BFC的高度时,浮动元素也参与计算
BFC应用场景解决块级元素垂直方向margin重叠我们来看下面这种情况:
style.box{width:px;height:px;background:rosybrown;color:#fff;margin:60pxauto;}/stylebodydivclass="box"nanjiu/divdivclass="box"南玖/div/body
按我们习惯性思维,上面这个box的margin-bottom是60px,下面这个box的margin-top也是60px,那他们垂直的间距按道理来说应该是px才对。(可事实并非如此,我们可以来具体看一下)
「从图中我们可以看到,两个box的垂直间距只有60px,并不是px!」
这种情况下的margin边距为两者的最大值,而不是两者相加,那么我们可以使用BFC来解决这种margin塌陷的问题。
style.box{width:px;height:px;background:rosybrown;color:#fff;margin:60pxauto;}.outer_box{overflow:hidden;}/stylebodydivclass="outer_box"divclass="box"nanjiu/div/divdivclass="box"南玖/div/body
由上面可以看到,我们通过给第一个box外面再包裹一层容器,并触发它形成BFC,此时的两个box就不属于同一个BFC了,它们的布局互不干扰,所以这时候他们的垂直间距就是两者间距相加了。
解决高度塌陷问题我们再来看这种情况,内部box使用float脱离了普通文档流,导致外层容器没办法撑起高度,使得背景颜色没有显示出来。
style.box{float:left;width:px;height:px;background:rosybrown;color:#fff;margin:60px;}.outer_box{background:lightblue;}/stylebodydivclass="outer_box"divclass="box"nanjiu/divdivclass="box"南玖/div/div/body
从这张图,我们可以看到此时的外层容器的高度为0,导致背景颜色没有渲染出来,这种情况我们同样可以使用BFC来解决,可以直接为外层容器触发BFC,我们来看看效果:
style.box{float:left;width:px;height:px;background:rosybrown;color:#fff;margin:60px;}.outer_box{display:inline-block;background:lightblue;}/stylebodydivclass="outer_box"divclass="box"nanjiu/divdivclass="box"南玖/div/div/body清除浮动
在早期前端页面大多喜欢用浮动来布局,但浮动元素脱离普通文档流,会覆盖旁边内容:
style.aside{float:left;width:px;height:px;background:lightpink;}.container{width:px;height:px;background:mediumturquoise;}/stylebodydivclass="outer_box"divclass="aside"nanjiu/divdivclass="container"南玖/div/div/body
我们可以通过触发后面这个元素形成BFC,从而来清楚浮动元素对其布局造成的影响
style.aside{float:left;width:px;height:px;background:lightpink;}.container{width:px;height:px;background:mediumturquoise;overflow:hidden;}/stylebodydivclass="outer_box"divclass="aside"nanjiu/divdivclass="container"南玖/div/div/bodyIFC(InlineFormattingContexts)行内级格式化上下文什么是IFC?
IFC全称:InlineFormattingContext,名为「行级格式化上下文」
如何触发IFC?块级元素中仅包含内联级别元素形成条件非常简单,需要注意的是当IFC中有块级元素插入时,会产生两个匿名块将父元素分割开来,产生两个IFC。
IFC布局规则在一个IFC内,子元素是水平方向横向排列的,并且垂直方向起点为元素顶部。子元素只会计算横向样式空间,,垂直方向样式空间不会被计算,。在垂直方向上,子元素会以不同形式来对齐(vertical-align)能把在一行上的框都完全包含进去的一个矩形区域,被称为该行的行框(linebox)。行框的宽度是由包含块(containingbox)和与其中的浮动来决定。IFC中的linebox一般左右边贴紧其包含块,但float元素会优先排列。IFC中的linebox高度由CSS行高计算规则来确定,同个IFC下的多个linebox高度可能会不同。当inlineboxes的总宽度少于包含它们的linebox时,其水平渲染规则由text-align属性值来决定。当一个inlinebox超过父元素的宽度时,它会被分割成多个boxes,这些boxes分布在多个linebox中。如果子元素未设置强制换行的情况下,inlinebox将不可被分割,将会溢出父元素。IFC应用场景元素水平居中当一个块要在环境中水平居中时,设置其为inline-block则会在外层产生IFC,通过text-align则可以使其水平居中。
style/*IFC*/.text_container{width:px;border:3pxsolidsalmon;margin-top:60px;text-align:center;}strong,span{/*border:1pxsolidcornflowerblue;*/margin:20px;background-color:cornflowerblue;color:#fff;}/stylebodydivclass="text_container"strong众里寻他千百度,南玖需要你