BFC和IFC
想要理解BFC与IFC,首先要理解另外两个概念:Box
和 FC
(即 formatting context)。
Box
一个页面是由很多个 Box
组成的,元素的类型和 display
属性决定了这个 Box
的类型。不同类型的 Box,会参与不同的 Formatting Context。
Block level
的box会参与形成BFC,比如display
值为block,list-item,table
的元素。
Inline level
的box会参与形成IFC,比如display
值为inline,inline-table,inline-block
的元素。
FC(Formatting Context)
它是W3C CSS2.1规范中的一个概念,定义的是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。
常见的Formatting Context
有:Block Formatting Context
(BFC | 块级格式化上下文) 和 Inline Formatting Context
(IFC |行内格式化上下文)。
下面就来介绍IFC和BFC的布局规则。
IFC布局规则:
在行内格式化上下文中,框(boxes)一个接一个地水平排列,起点是包含块的顶部。水平方向上的 margin
,border
和 padding
在框之间得到保留。框在垂直方向上可以以不同的方式对齐:它们的顶部或底部对齐,或根据其中文字的基线对齐。包含那些框的长方形区域,会形成一行,叫做行框。
BFC的布局规则
BFC(Block Formatting Context) 块级格式化上下文。官方的大致解释:它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用,当涉及到可视化布局的时候,Block Formatting Context 提供了一个环境 HTML元素在这个环境中按照一定规则进行布局。
总结一句话:BFC 的目的就是形成一个完全独立的空间,让空间中的子元素不会影响到外面的布局
1.内部的盒子会在垂直方向,一个个地放置;
2.盒子垂直方向的距离由margin决定,属于同一个BFC的两个相邻Box的上下margin会发生重叠;
3.每一个元素的左边,与包括的盒子的左边相接触,即使存在浮动也是如此;
4.BFC的区域不会与float重叠;
5.BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此;
6.计算BFC的高度时,浮动元素也參与计算。
如何形成BFC
如何才能成形成这样一种独立的空间呢?
通过为元素设置一些CSS属性就可以触发,最常见的触发规则有4种(都是让元素脱离文档流)。
-
float不为none可
-
position不为relative和static
-
overflow为auto、scroll和hidden
-
display的值为table-cell、inline-block或table-caption
BFC可以解决什么问题
1.解决浮动元素令父元素高度塌陷的问题
假设页面中有一个父元素和几个子元素,几个子元素都设为浮动时, 就会产生父元素高度坍塌,这是因为浮动的子元素脱离的文档流,被提起来形成新的VIP队列,下方普通队列中的元素无法触及它,父元素也检测不到他的存在而无法被撑开,看起来就是父元素高度坍塌了,后面的布局也会乱掉。
解决方法:
overflow:hidden;/display:table-cell;/display:inline-block;/position:fixed/position:absolute;
2.出于布局需要,可能无法给父元素设置这些属性,这时可采用其他方法
1.让父元素也浮动起来,让父元素和子元素一起脱离文档流,这样父元素就能自适应子元素的高度。优点:代码量少,缺点:会影响之后的元素排列
2.给父元素添加固定高度,这种只适用于已知子元素的高度,且不易维护,不推荐。
3.在浮动的子元素后面增加一个空元素,设置clear:both
来清除浮动,但会增加无意义的标签,不利于维护
4.为浮动的最后一个子元素设置伪元素::after{clear:both}
这个办法和前一个是同一原理,只不过用伪类替代了空元素。优点:结构和语义完全正确,缺点:复用不当会导致代码量增加。
2.解决自适应布局的问题
两栏布局(左侧边栏定宽,右侧主体随页面宽度自适应变化)
这种布局通常使用浮动来实现的,它利用了块级元素会尽可能沾满一行的特性,使得右边的元素可以随着页面宽度变化而变化,右利用了浮动特性,让左侧元素覆盖在右侧元素上面,同时还能挤开下方元素里的内容,让页面看起来是两栏的效果。
但随着右边元素里的文字增加,超出了左边的元素之后,文字就会流动到最左侧,看起来就是文字环绕左侧元素。
因此这里为右侧元素触发BFC,触发了BFC的容器就是页面上的一个完全隔离开的容器,容器里的子元素绝对不会影响到外面的元素。
还有其他方法可以做这样的自适应布局
3.解决外边距垂直方向重合问题
兄弟元素之间的外边距,在垂直方向会取最大值而不是取和。
解决方法:触发BFC来防止他们之间的相互影响,比如为其中 一个p元素外面包裹一层父元素,并且触发父元素BFC比如overflow:hidden
这样打破原有格局就不会再重叠了
同样还有另外解决方案:用padding来替代margin,但是如果根据设计本来就需要设置padding样式,就没办法用了。