深入理解BFC原理及其在布局中的应用
谈谈你对盒模型的理解?
当面试官问到这个问题,如果你只说出W3C标准盒模型和IE盒模型:
标准盒模型中,
width
和height
等于内容区(content
)的宽高;
而IE盒模型中,width
和height
等于content
+padding
+border
的总宽高。
这个答案显然是不够的。
要是你能稍微扩展一点,说出CSS3中对盒模型的类型设置属性:
box-sizing: content-box;
—— 标准盒模型box-sizing: border-box;
—— IE盒模型
同时联想到js中对盒模型样式属性的一些操作:
读取元素的内联样式属性及修改元素的样式属性 ——
元素.style.样式名
/元素.style.样式名 = 样式值
获取元素的当前样式对象 ——
元素.currentStyle
/getComputedStyle(元素, null)
读取元素的可见宽度和高度(content+padding) ——
元素.clientWidth
/元素.clientHeight
读取元素的整个宽度和高度(content+padding+border) ——
元素.offsetWidth
/元素.offsetHeight
这就应该是一个比较好的回答了。
当然,如果你还能充分延伸,再多说一点:
盒模型 → 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 context
。inline-level box
:display
属性为inline/inline-block/inline-table
的元素,会生成inline-level box
,并且参与inline formatting context
。
什么是Formatting Context
:
CSS2.1规范中的一个概念,它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。
最常见的Formatting Context
有Block Formatting Context
(简称BFC)和Inline Formatting Context
(简称IFC)。
由于IFC在各浏览器有不同的实现和规则,我们一般只考虑BFC。
BFC渲染规则
BFC直译为块级格式化上下文,它是一个独立的渲染区域,只有block-level box
参与,它规定了内部的盒子如何布局,并且与这个区域的外部毫不相干。
内部的盒子会在垂直方向一个接一个的放置。
BFC的区域不会与浮动的盒子重叠。
内部的Box垂直方向的距离由
margin
决定,属于同一个 BFC的两个 相邻 的Box,垂直方向上margin
会发生重叠。计算BFC的高度时,浮动元素也参与计算。
BFC渲染规则在布局中的应用
第一条规则自不用多说,块级盒子独占一行,垂直方向一个接一个放置。
利用第二条规则,可以很轻松地实现两列布局,只需要让右栏生成BFC:左栏定宽右栏自适应。
由于垂直方向
margin
重叠,上下两个兄弟box的margin
会取较大值,推荐的解决方案是在其中一个box的外层加一个div
并让其开启BFC,这样两个box就不相干了:兄弟盒子margin重叠。还有一个垂直方向
margin
重叠的情况,是父子box的margin
传递,当同一个BFC中的父子盒子相邻时,给子盒子设置的上外边距,会传递,变成父盒子的外边距:父子盒子margin传递。由于这条规则,我们可以让一个元素生成BFC,从而能够包裹住浮动的子元素,解决高度塌陷问题。
BFC什么时候出现(哪些元素会生成BFC)
根元素
float
属性不为none
position
属性为absolute
或fixed
overflow
属性不为visible
display
为inline-block/table-cell/table-caption/flex/inline-flex