1. bfc的概念
BFC(Block formatting context),即块级格式化上下文,它作为 HTML 页面上的一个独立渲染区域,只有区域内元素参与渲染,且不会影响其外部元素。
W3C 对 BFC 的定义如下:
浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks,table-cells 和 table-captions),以及 overflow 值不为 “visiable”
的块级盒子,都会为他们的内容创建新的 BFC(块级格式上下文)。
2. 如何创建bfc,即bfc的触发条件
- 根元素,即 HTML 元素。
- 浮动元素,float 除了 none 以外的值。
- 定位元素,position 的值为 absolute 或 fixed,不是 static 或者 relative。
- display 的值是 inline-block、table-cell、flex、table-caption或者 inline-flex 。
- overflow 除了 visible 以外的值(hidden,auto,scroll )。
只要满足上述 5 个 CSS 条件之一即可。
3. bfc的布局规则
- BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 内部的 Box 会在垂直方向,一个接一个地放置。
- Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠。
- 每个盒子(块盒与行盒)的 margin box 的左边,与包含块 border box 的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
- BFC 的区域不会与 float box重叠(可以用此来解决自适应布局的问题)。
- 计算 BFC 的高度时,浮动元素也参与计算(撑开父元素,不会出现高度塌陷问题)。
4. bfc的应用
(1)避免外边距重叠(防止margin塌陷)
根据 BFC 布局规则:
Box 垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠。
折叠的结果:
两个相邻的外边距都是正数时,折叠结果是它们两者之间的较大值。
两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
两个外边距一正一负时,折叠结果是两者的相加的和。
解决方法:
当两个相邻块级子元素分属于不同的 BFC 时,就可以阻止margin 重叠。
操作方法:
给其中一个 p 外面包一个 div,然后通过触发外面这个 div 的 BFC,就可以阻止这两个 p 的 margin 重叠。
(2) 清除浮动
浮动元素是会脱离文档流的(绝对定位元素会脱离文档流)。
如果一个没有高度或者 height 是 auto 的容器的子元素是浮动元素,则该容器的高度是不会被撑开的。我们通常会利用伪元素(:after或者:before)来解决这个问题。
通过给父元素设置BFC属性,来实现清除浮动,从而解决容器高度不会被撑开的问题。
<div class="container">
<div>内容1</div>
<div>内容2</div>
</div>
<style>
.container {
/* 创建了一个BFC */
overflow: hidden;
background-color: skyblue;
}
.container div {
float: left;
background-color: steelblue;
margin: 10px;
}
</style>
拓展1:清除浮动的方法的四种方式
当容器的高度为auto,且容器的内容中有浮动(float为left或right)的元素,在这种情况下,容器的高度不能自动伸长以适应内容的高度,使得内容溢出到容器外面而影响(甚至破坏)布局的现象。这个现象叫浮动溢出,为了防止这个现象的出现而进行的CSS处理,就叫CSS清除浮动。
<div class="father">
<div class="box1">1</div>
<div class="box2">2</div>
</div>
1)给父元素添加高度
父元素高度的设置一定要大于子元素中高度最高的盒子
<style>
.father{
width: 100%;
height: 100px;
border: 2px solid red;
}
</style>
2)给父元素设置overflow:hidden
<style>
.father{
width: 100%;
border: 2px solid red;
overflow: hidden;
}
</style>
3)添加空标签:clear:both
在需要清除浮动的标签后面添加一个空标签,给其加上clear:both
<div class="father">
<div class="box1">1</div>
<div class="box2">2</div>
<div class="clear"></div>
</div>
<script>
.clear{
clear: both;
}
</script>
4)使用after伪元素清除浮动
<style>
.father:after{
content: "";
display: block;
height: 0;
clear:both;
visibility: hidden;
}
.father{
zoom: 1;
/*IE6清除浮动的方式 只有IE6-IE7执行,其他浏览器不执行*/
}
</style>
(3)实现两栏布局
// HTML代码
<div class="box">
<div class="left">左边固定宽度为200px</div>
<div class="right">右边自适应</div>
</div>
// CSS代码
<style>
.box {
background-color: pink;
height: 300px;
}
.left {
float: left;
width: 200px;
height: 200px;
background-color: royalblue;
}
.right {
height: 300px;
background-color: skyblue;
}
</style>
效果如图
因为BFC 的区域不会与 float box 重叠,所以我们让 right 单独成为一个 BFC,right 会自动的适应宽度,这样就可以实现自适应两栏布局效果了
<style>
.box {
background-color: pink;
height: 300px;
}
.left {
float: left;
width: 200px;
height: 200px;
background-color: royalblue;
}
.right {
/* 创建了一个BFC */
overflow: hidden;
height: 300px;
background-color: skyblue;
}
</style>
效果如图
拓展2:CSS中常见的布局方案
· 普通流定位
1.元素按照其在HTML中的先后位置至上而下进行布局
2.行内元素水平排列,直至当行被占满然后换行,块级元素则会被渲染为完整的一整行
3.所有元素默认都是普通流定位
· 浮动 float
元素首先按照普通流的位置出现,然后根据浮动的方向尽可能向左或向右偏移
· 绝对定位 position
元素整体会脱离普通流,因此绝对定位的元素不会对兄弟元素造成影响