介绍下 BFC、IFC、GFC 和 FFC?
BFC(Block Formatting Contexts)块级格式化上下文
什么是 BFC?
BFC
全称: Block Formatting Context
, 名为 块级格式化上下文。
W3C
官方解释为: BFC
它决定了元素如何对其内容进行定位,以及与其它元素的关系和相互作用,当涉及到可视化布局时, Block Formatting Context
提供了一个环境, 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 会发生重叠。
- 每个元素的 margin box 的左边, 与包含块 border box 的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
- BFC 的区域不会与 float box 重叠。
- BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 计算 BFC 的高度时,浮动元素也参与计算
BFC 应用场景
解决块级元素垂直方向 margin 重叠
我们来看下面这种情况:
<style> .box{ width:180px; height:180px; background:rosybrown; color:#fff; margin: 60px auto; } </style> <body> <div class="box">box1</div> <div class="box">box2</div> </body>
按我们习惯性思维,上面这个 box 的 margin-bottom
是 60px
,下面这个 box 的 margin-top
也是 60px
,那他们垂直的间距按道理来说应该是 120px
才对。(可事实并非如此,我们可以来具体看一下)
这种情况下的 margin 边距为两者的最大值,而不是两者相加,那么我们可以使用 BFC 来解决这种 margin 塌陷的问题。
<style> .box{ width:180px; height:180px; background:rosybrown; color:#fff; margin: 60px auto; } .outer_box{ overflow: hidden; } </style> <body> <div class="outer_box"> <div class="box">nanjiu</div> </div> <div class="box">南玖</div> </body>
解决高度塌陷问题
我们再来看这种情况,内部 box 使用 float
脱离了普通文档流,导致外层容器没办法撑起高度,使得背景颜色没有显示出来。
<style> .box{ float:left; width:180px; height:180px; background:rosybrown; color:#fff; margin: 60px; } .outer_box{ background:lightblue; } </style> <body> <div class="outer_box"> <div class="box">nanjiu</div> <div class="box">南玖</div> </div> </body>
我们可以看到此时的外层容器的高度为 0,导致背景颜色没有渲染出来,这种情况我们同样可以使用 BFC 来解决,可以直接为外层容器触发 BFC,我们来看看效果:
<style> .box{ float:left; width:180px; height:180px; background:rosybrown; color:#fff; margin: 60px; } .outer_box{ display:inline-block; background:lightblue; } </style> <body> <div class="outer_box"> <div class="box">nanjiu</div> <div class="box">南玖</div> </div> </body>
清除浮动
在早期前端页面大多喜欢用浮动来布局,但浮动元素脱离普通文档流,会覆盖旁边内容:
<style> .aside { float: left; width:180px; height: 300px; background:lightpink; } .container{ width:500px; height:400px; background:mediumturquoise; } </style> <body> <div class="outer_box"> <div class="aside">nanjiu</div> <div class="container">南玖</div> </div> </body>
我们可以通过触发后面这个元素形成 BFC,从而来清楚浮动元素对其布局造成的影响
<style> .aside { float: left; width:180px; height: 300px; background:lightpink; } .container{ width:500px; height:400px; background:mediumturquoise; overflow: hidden; } </style> <body> <div class="outer_box"> <div class="aside">nanjiu</div> <div class="container">南玖</div> </div> </body>
什么是 IFC?
IFC
全称: Inline Formatting Context
,名为行级格式化上下文
如何触发 IFC?
- 块级元素中仅包含内联级别元素
形成条件非常简单,需要注意的是当 IFC 中有块级元素插入时,会产生两个匿名块将父元素分割开来,产生两个 IFC。
IFC 布局规则
- 在一个 IFC 内,子元素是水平方向横向排列的,并且垂直方向起点为元素顶部。
- 子元素只会计算横向样式空间,【padding、border、margin】,垂直方向样式空间不会被计算,【padding、border、margin】。
- 在垂直方向上,子元素会以不同形式来对齐(vertical-align)
- 能把在一行上的框都完全包含进去的一个矩形区域,被称为该行的行框(line box)。行框的宽度是由包含块(containing box)和与其中的浮动来决定。
- IFC 中的
line box
一般左右边贴紧其包含块,但 float 元素会优先排列。 - IFC 中的
line box
高度由 CSS 行高计算规则来确定,同个IFC
下的多个line box
高度可能会不同。 - 当
inline boxes
的总宽度少于包含它们的line box
时,其水平渲染规则由text-align
属性值来决定。 - 当一个
inline box
超过父元素的宽度时,它会被分割成多个boxes
,这些boxes
分布在多个line box
中。如果子元素未设置强制换行的情况下,inline box
将不可被分割,将会溢出父元素。
IFC 应用场景
元素水平居中
当一个块要在环境中水平居中时,设置其为 inline-block 则会在外层产生 IFC,通过 text-align 则可以使其水平居中。
<style> /* IFC */ .text_container{ width: 650px; border: 3px solid salmon; margin-top:60px; text-align: center; } strong,span{ margin: 20px; background-color: cornflowerblue; color:#fff; } </style> <body> <div class="text_container"> <strong>string 1</strong> <span>string 2</span> </div> </body>
多行文本水平垂直居中
创建一个 IFC,然后设置其 vertical-align:middle
,其他行内元素则可以在此父元素下垂直居中。
<style> .text_container{ text-align: center; line-height: 300px; width: 100%; height: 300px; background-color: turquoise; font-size: 0; } p{ line-height: normal; display: inline-block; vertical-align: middle; background-color: coral; font-size: 18px; padding: 10px; width: 360px; color: #fff; } </style> <body> <div class="text_container"> <p> string 1 <strong>string 2</strong> </p> </div> </body>
GFC(Grid Formatting Contexts)栅格格式化上下文
什么是 GFC?
GFC
全称: Grids Formatting Contexts
,名为网格格式上下文
简介: CSS3 引入的一种新的布局模型——Grids 网格布局,目前暂未推广使用,使用频率较低,简单了解即可。 Grid 布局与 Flex 布局有一定的相似性,都可以指定容器内部多个项目的位置。但是,它们也存在重大区别。 Flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局。Grid 布局则是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以看作是二维布局。Grid 布局远比 Flex 布局强大。
如何触发 GFC?
当为一个元素设置 display
值为 grid
或者 inline-grid
的时候,此元素将会获得一个独立的渲染区域。
GFC 布局规则
通过在 网格容器(grid container)
上定义 网格定义行(grid definition rows)
和 网格定义列(grid definition columns)
属性各在网格项目(grid item)上定义网格行(grid row)和网格列(grid columns)为每一个网格项目(grid item)定义位置和空间(具体可以在 MDN 上查看)
GFC 应用场景
任意魔方布局
这个布局使用用 GFC 可以轻松实现自由拼接效果,换成其他方法,一般会使用相对/绝对定位,或者 flex 来实现自由拼接效果,复杂程度将会提升好几个等级。
<style> .magic{ display: grid; grid-gap: 2px; width:300px; height:300px; } .magic div{ border: 1px solid coral; } .m_1{ grid-column-start: 1; grid-column-end: 3; } .m_3{ grid-column-start: 2; grid-column-end: 4; grid-row-start: 2; grid-row-end: 3; } </style> <body> <div class="magic"> <div class="m_1">1</div> <div class="m_2">2</div> <div class="m_3">3</div> <div class="m_4">4</div> <div class="m_5">5</div> <div class="m_6">6</div> <div class="m_7">7</div> </div> </body>
FFC(Flex Formatting Contexts)弹性格式化上下文
什么是 FFC?
FFC
全称: Flex Formatting Contexts
,名为弹性格式上下文
简介: CSS3 引入了一种新的布局模型——flex 布局。 flex 是 flexible box 的缩写,一般称之为弹性盒模型。和 CSS3 其他属性不一样,flexbox 并不是一个属性,而是一个模块,包括多个 CSS3 属性。flex 布局提供一种更加有效的方式来进行容器内的项目布局,以适应各种类型的显示设备和各种尺寸的屏幕,使用 Flex box 布局实际上就是声明创建了 FFC(自适应格式上下文)
如何触发 FFC?
当 display
的值为 flex
或 inline-flex
时,将生成弹性容器(Flex Containers), 一个弹性容器为其内容建立了一个新的弹性格式化上下文环境(FFC)
FFC 布局规则
- 设置为
flex
的容器被渲染为一个块级元素 - 设置为
inline-flex
的容器被渲染为一个行内元素 - 弹性容器中的每一个子元素都是一个弹性项目。弹性项目可以是任意数量的。弹性容器外和弹性项目内的一切元素都不受影响。简单地说,Flexbox 定义了弹性容器内弹性项目该如何布局
注意:FFC 布局中,float、clear、vertical-align 属性不会生效。
Flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局。Grid 布局则是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以看作是二维布局。Grid 布局远比 Flex 布局强大。
FFC 应用场景
这里只介绍它对于其它布局所相对来说更方便的特点,其实 flex 布局现在是非常普遍的,很多前端人员都喜欢用 flex 来写页面布局,操作方便且灵活,兼容性好。
自动撑开剩余高度/宽度
看一个经典两栏布局:左边为侧边导航栏,右边为内容区域,用我们之前的常规布局,可能就需要使用到 css
的 calc
方法来动态计算剩余填充宽度了,但如果使用 flex 布局的话,只需要一个属性就能解决这个问题:
calc 动态计算方法:
<style> .outer_box { width:100%; } .aside { float: left; width:180px; height: 300px; background:lightpink; } .container{ width:calc(100% - 180px); height:400px; background:mediumturquoise; overflow: hidden; } </style> <body> <div class="outer_box"> <div class="aside">box1</div> <div class="container">box2</div> </div> </body>
使用 FFC:
<style> .outer_box { display:flex; width:100%; } .aside { float: left; width:180px; height: 300px; background:lightpink; } .container{ flex: 1; height:400px; background:mediumturquoise; overflow: hidden; } </style> <body> <div class="outer_box"> <div class="aside">box1</div> <div class="container">box2</div> </div> </body>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论