首先理解一下 BFC IFC GFC FFC 然后重点讲一下 BFC原理及其应用
Formatting Context 简称 FC
是W3C css2 规范中的一个概念 它是页面中的一块渲染区域 并且有一套渲染规则 它决定了其子元素将如何定位 以及和其他元素的关系和相互作用
最常见formatting context有block formatting context(简称BFC)和inline formatting context(简称IFC)
IFC
IFC – Inline Formatting Context --直译 – 行内格式化上下文
IFC的line box高度由其包含行内元素中最高的实际高度计算而来(不受竖直方向的padding/margin影响)
IFC布局规则
- 框会从包含块的顶部开始 一个接一个地水平摆放
- 摆放这些框的时候 在水平方向上的外边距 边框 内边距所占用的空间都会被考虑在内 在垂直方向上 这些框可能会以不同形式来对齐(顶部 底部或文本基线对齐) 能把在一行上的框都完全包含进去的一个矩形区域 被称为该行的行框 水平的margin padding border有效 垂直无效 不能指定宽高
- 行框的宽度由包含块和存在的浮动来决定
影响IFC内布局的css
font-size line-height height vertical-aligin
IFC的特性
- IFC中的line box一般左右都贴紧整个IFC 但是会因为float元素而扰乱 float元素会位于IFC与line box之间 使得line box宽度缩短
- IFC中不可能有块级元素的 当插入块级元素时(如p中插入div) 会产生两个匿名块与div分隔开 即产生两个IFC 每个IFC对外表现为块级元素 与div垂直排列
IFC的应用
- 水平居中:当一个块要在环境中水平居中时 设置其为inline-block则会在外层产生IFC 通过text-align则可以使其水平居中
- 垂直居中:创建一个IFC 用其中一个元素撑开父元素的高度 然后设置其vertical-align:middle 其他行内元素则可以在此父元素下垂直居中
GFC
GFC – GridLayout Formatting Context – 直译 – 网格布局格式化上下文
当一个元素设置display值为grid的时候 此元素将会获得一个独立的渲染区域 可以通过在网格容器(grid container)上定义网格定义行(row)和列(columns)
属性各在网格项目item上定义网格行和列 为每一个网格项目定义位置和空间
GFC将改变传统的布局模式 让布局从一维布局变成了二维布局 简单来说 布局不再局限于单个维度了 这个时候要实现类似九宫格 拼图之类的布局效果显得格外的容易
(可以参考网上的文章去深入了解)
FFC
FFC – Flex Formatting Context – 直译 – 自适应格式化上下文
display为flex或者inline-flex的元素将会生成自适应容器 flex container
Flex Box由伸缩容器和伸缩项目组成 通过设置元素的display属性为flex或者inline-flex可以得到一个伸缩容器 设置flex的容器被渲染为一个块级元素 而设置为inline-flex的容器则渲染为一个行内元素
伸缩容器中的每一个子元素都是一个伸缩项目 伸缩项目可以是任意数量的 伸缩容器外和伸缩项目内的一切元素都不受影响 简单来说FlexBox定义了伸缩容器内伸缩项目该如何布局
(可以参考网上的文章去深入了解)
FFC和BFC有点类似 有几点区别了解一下:
- FlexBox不支持::first-line 和 ::first-letter 这两种伪元素
- vertical-align对flexbox中的子元素是没有效果的
- float和clear属性对flexbox中的子元素是没有效果的 也不会使子元素脱离文档流 但对flexbox有作用
- 多栏布局column在flexbox中也是失效的 不能使用多栏布局在flexbox排列其下多子元素
- flexbox下的子元素不会继承父级容器的宽
下面重点讲一下BFC 会根据三个例子讲一下BFC的应用 首先了解一下基本概念
BFC – Block Formatting Context
直译是–块级格式化上下文 它是一个独立渲染区域 只有Block-level box参与 它规定了内部如何布局 并且与这个区域外部毫不相干
解释 BFC 之前 先理解 Box Formatting Context的概念
Box–css布局的基本单位
直观来说 就是一个页面由很多个box组成的 元素的类型和display属性 决定了这个box的类型 不同类型的box 会参与不同的formatting context(一个决定如何渲染文档的容器) 因此box内的元素会以不同的方式渲染 让我们看看有哪些盒子:
– block-level box:display属性为block list-item table的元素 会生成block-level box 并参与block formatting conext
– inline-level box:display属性为inline inline-block inline-table的元素 会生成inline-level box 并参与 inline formatting context
– run-in box 是一个块/行内元素混合 可以使某些块级元素成为下一个元素的行内部分
BFC是一个独立的布局环境 其中的元素布局是不受外界的影响 并且在一个BFC中 块盒与行盒都会垂直的沿着其父元素的边框排列
BFC的布局规则
–内部的box会在垂直方向 一个接一个地放置
–box垂直方向的距离由margin决定 属于同一个BFC的两个相邻box的margin会发生重叠
–每个盒子的margin box的左边 与包含border box的左边相接触(对于从左往右的格式化 否则相反) 即使存在浮动也是如此
–BFC的区域不会与float box重叠
–BFC就是页面上的一个隔离的独立容器 容器里面的子元素不会影响到外面的元素 反之也是如此
–计算BFC的高度时 浮动元素也参与计算
如何创建BFC
–float的值不是none
–position的值不是static或者relative
–display的值是inline-block table-cell flex table-caption或者inline-flex
–overflow的值不是visible
BFC的作用
- 利用bfc避免margin重叠
例子
页面的生成效果如下
根据第二条 属于同一个bfc的两个相邻的box会发生margin重叠 所以可以设置 两个不同的bfc 也就是把第二个p用div包起来 然后激活它使其成为一个bfc
页面生成效果如下 很明显距离明显拉开了
2. 自适应两栏布局
根据bfc的第三个规则:每个盒子的margin box的左边 也包含快border box的左边相接触 即使存在浮动也是如此
页面效果如下
又因为 bfc的区域不会与float box重叠
让right单独成为一个bfc 只需在 right的样式下加 overflow:hidden
页面效果就如下
right会自动的适应宽度 这时候就形成了一个两栏自适应的布局
3. 清除浮动
当不给父节点设置高度 子节点设置浮动的时候 会发生高度塌陷 这时候就需要清除浮动
例如
页面效果如下
这时候根据最后一条:计算bfc的高度时 浮动元素也参与计算
给父节点激活bfc 加入 .par{overflow:hidden} 即可
加入后的页面效果如下
总结:
BFC就是页面上的一个隔离的独立容器 容器里面的子元素不会影响到外面的元素 反之也是如此
因为BFC的内部元素和外部的元素绝对不会互相影响 因此 当BFC外部存在浮动时 它不应该影响BFC内部box的布局 BFC会通过变窄 而不与浮动有重叠
同样的当BFC内部有浮动时 为了不影响外部元素的布局 BFC计算高度时会包括浮动的高度 避免margin重叠也是这样的一个道理