【转】浅析BFC及其作用
1. 什么是BFC
BFC(block formatting context):简单来说,BFC 就是一种属性,这种属性会影响着元素的定位以及与其兄弟元素之间的相互作用。
中文译为块级格式化上下文。是 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。 在进行盒子元素布局的时候,BFC提供了一个环境,在这个环境中按照一定规则进行布局不会影响到其它环境中的布局。比如浮动元素会形成BFC,浮动元素内部子元素的主要受该浮动元素影响,两个浮动元素之间是互不影响的。 也就是说,如果一个元素符合了成为BFC的条件,该元素内部元素的布局和定位就和外部元素互不影响(除非内部的盒子建立了新的 BFC),是一个隔离了的独立容器。(在 CSS3 中,BFC 叫做 Flow Root)。
2. 形成 BFC 的条件
- 根元素或其他包含它的元素
- 浮动(元素的float不为none)
- 绝对定位元素(position为absolute或者fixed)
- 行内块(display:inline-block)
- 表格单元格(display:table-cell,html表格单元格默认属性)
- 表格标题(display:table-caption,html表格标题默认属性)
- overflow的值不为visible的元素(hidden,auto,scroll)
- 弹性盒flex boxes(display:flex或者inline-flex)
其中,最常见的就是overflow:hidden、float:left/right、position:absolute。也就是说,每次看到这些属性的时候,就代表了该元素已经创建了一个BFC了。
3. BFC的 特性
- 内部的盒会在垂直方向一个接一个排列(可以看作BFC中有一个的常规流);
- 处于同一个BFC中的元素相互影响,可能会发生外边距叠加,如果这两个相邻的块框不属于同一个块级格式化上下文,那么它们的外边距就不会叠加。;
- 每个元素的margin box的左边,与容器块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此;
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然;
- 计算BFC的高度时,考虑BFC所包含的所有元素,连浮动元素也参与计算;
6. 浮动盒区域不叠加到BFC上;
BFC包含创建该上下文元素的所有子元素,但不包括创建了新BFC的子元素的内部元素,也就是一个元素不能同时存在于两个BFC中。
通俗地来说:创建了 BFC的元素就是一个独立的盒子,里面的子元素不会在布局上影响外面的元素,反之亦然,同时BFC仍然属于文档中的普通流。
4. BFC常见作用
(1)包含浮动元素
问题案例:高度塌陷问题:在通常情况下父元素的高度会被子元素撑开,而在这里因为其子元素为浮动元素所以父元素发生了高度坍塌,上下边界重合。这时就可以用bfc来清除浮动了。
(2)不被浮动元素覆盖
问题案例: div浮动兄弟遮盖问题:由于左侧块级元素发生了浮动,所以和右侧未发生浮动的块级元素不在同一层内,所以会发生div遮挡问题。可以给蓝色块加 overflow: hidden,触发bfc来解决遮挡问题。
(3)BFC 会阻止外边距折叠
问题案例:margin塌陷问题:在标准文档流中,块级标签之间竖直方向的margin会以大的为准,这就是margin的塌陷现象。可以用overflow:hidden产生bfc来解决。
5. 从实际代码来分析BFC
实例一
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>高度坍塌问题-BFC模式解析</title>
<style>
* {
margin: 0;
padding: 0;
}
.box{
background:#888; /* 灰色 */
height: 100%;
margin-left: 50px;
}
.left{
background: #73DE80; /* 绿色 */
opacity: 0.5;
border: 3px solid #F31264;
width: 200px;
height: 200px;
float: left;
}
.right{ /* 粉色 */
background: #EF5BE2;
opacity: 0.5;
border: 3px solid #F31264;
width:400px;
min-height: 100px;
} </style>
</head>
<body>
<div class='box'>
<div class='left'></div>
<div class='right'></div>
</div>
</body>
</html>
绿色框('#left')向左浮动,它创建了一个新BFC,但暂时不讨论它所创建的BFC。由于绿色框浮动了,它脱离了原本normal flow的位置,因此,粉色框('#right')就被定位到灰色父元素的左上角(特性3:元素左边与容器左边相接触),与浮动绿色框发生了重叠。
同时,由于灰色框('#box')并没有创建BFC,因此在计算高度的时候,并没有考虑绿色框的区域,发生了高度坍塌,这也是常见问题之一。
实例二
现在通过设置overflow:hidden来创建BFC闭合浮动,再看看效果如何。
.BFC{
overflow: hidden;
} <div class='box BFC'>
<div class='left'> </div>
<div class='right'> </div>
</div>
灰色框创建了一个新的BFC后,高度发生了变化,计算高度时它将绿色框区域也考虑进去了(特性5:计算BFC的高度时,浮动元素也参与计算);而绿色框和红色框的显示效果仍然没有任何变化。
实例三
现在,现将一些小块添加到粉色框中,看看效果:
<style>
.little{
background: #fff;
width: 50px;
height: 50px;
margin: 10px;
float: left;
}
</style> <div class='box BFC'>
<div class='left'> </div>
<div class='right'>
<div class='little'></div>
<div class='little'></div>
<div class='little'></div>
</div>
</div>
由于粉红框没有创建新的BFC,因此粉色框中白色块受到了绿色框的影响,被挤到了右边去了(特性6:浮动盒区域不叠加到BFC上)。先不管这个,看看白色块的margin,发生了外边距叠加。
实例四
利用同实例二中一样的方法,为粉色框创建BFC,防止与浮动元素(绿色框)重叠:
<div class='box BFC'>
<div class='left'> </div>
<div class='right BFC'>
<div class='little'></div>
<div class='little'></div>
<div class='little'></div>
</div>
</div>
一旦粉色框创建了新的BFC以后,粉色框就不与绿色浮动框发生重叠了,同时内部的白色块处于隔离的空间(特性4:BFC就是页面上的一个隔离的独立容器),白色块也不会受到绿色浮动框的挤压。
总结
以上就是BFC的分析,BFC的概念比较抽象,但通过实例分析应该能够更好地理解BFC。在实际中,利用BFC可以闭合浮动(实例二),防止与浮动元素重叠(实例四)。同时,由于BFC的隔离作用,可以利用BFC包含一个元素,防止这个元素与BFC外的元素发生margin collapse。
5. 那么到底为什么坍塌?
float 脱离了普通流,并且创建了新的BFC,而父元素不具备产生 BFC 的条件,所以它的高度为0。
如何解决?
通过了解BFC的特性我们知道,BFC会把它包含的浮动元素高度也算在里面,也就是闭合浮动。拿 overflow: auto 举例:overflow: auto 并不会闭合浮动,而是 overflow: auto 会创建一个新的BFC,避免浮动的元素侵入其他元素。
IE6-7有一个特有的属性就是haslayout,当一个元素的hasLayout属性值为true时,我们说这个元素有一个布局(layout),它负责对自己和可能的后代元素进行尺寸计算和定位,当属性值为false时,它的尺寸和位置由最近拥有布局的祖先元素控制。
很多情况下,把 hasLayout的状态改成true 可以解决很大部分ie下显示的bug。 hasLayout属性不能直接设定,通过设定一些特定的css属性来触发并改变 hasLayout 状态。
元素hasLayout而导致的问题其实一般都很容易发现:往往是内容出现错位甚至完全不可见。 如:当一个元素内含浮动或绝对定位的内容时,它通常会表现出奇怪和错误的行为
一般如果是因为layout而引起的显示不符期望效果的话,在ff下会表现正常,而在ie下会出现错误。这个时候可以尝试触发父容器及其中的子容器的haslayout属性,通常可以通过加上zoom: 1;来调试。直到找到了产生问题的元素,再进行针对性的修正。最好的办法是对这个元素设置尺寸属性。但是,有时不便指定尺寸属性的情况下,就只能寻找替代方案了。对于ie7 ,最好的办法是设置最小高度属性为0;这个技术是无害的,因为0本来就是这个属性的初始值。而且没有必要对其他浏览器隐藏这个属性。而对于ie6和更早版本中触发一个元素hasLayout的方法是在overflow属性是visible的情况下设置这个元素的高度属性为1%,然后对其他浏览器隐藏这个设置。这种技术就是著名的Holly hack。
触发hasLayout的条件:
position: absolute
float: left|right
display: inline-block
width: 除 “auto” 外的任意值
height: 除 “auto” 外的任意值 (例如很多人闭合浮动会用到 height: 1% )
zoom: 除 “normal” 外的任意值
writing-mode: tb-rl
在 IE7 中,一些额外的属性也可以触发该属性: min-height: (任何值) max-height: (任何值除了none)
min-width: (任何值)
max-width: (任何值除了none)
overflow: hidden|scroll|auto ( 这个属性在IE之前版本中没有触发 layout 的功能。 )
overflow-x|-y: hidden|scroll|auto (CSS3 盒模型中的属性,尚未得到浏览器的广泛支持。他们在之前IE版本中同样没有触发 layout 的功能)
综上所述:
在支持BFC的浏览器(IE8+,firefox,chrome,safari)通过创建新的BFC闭合浮动;
在不支持 BFC的浏览器 (IE6-7),通过触发 hasLayout 闭合浮动。
参考: 高度坍塌问题--BFC模式解析
【转】浅析BFC及其作用的更多相关文章
- 浅析BFC及其作用
本文链接:https://blog.csdn.net/riddle1981/article/details/52126522
- 浅析BFC布局的概念以及作用
BFC的概念以及作用 BFC的定义: (Block formatting context)直译为"块级格式化上下文".它是一个独立的渲染区域,只有Block-level box参与 ...
- BFC的作用及其应用
简单介绍BFC BFC 就是块级格式化上下文,是页面盒模型布局中的一种 CSS 渲染模式,相当于一个独立的容器,里面的元素和外部的元素相互不影响. 创建 BFC 的方式有: 1.html的根元素 2. ...
- 轻谈BFC
BFC 定义 CSS2.1的定义 Block formatting contexts 9.4.1 Block formatting contexts Floats, absolutely positi ...
- BFC 原理
BFC:Block-level box + Forating + Context; ------->块元素 决定其子元素如何定位, ...
- BFC的概念及作用
在了解什么是BFC之前,首先得明白什么是Box , Formatting Context (一个决定如何渲染文档的容器)的概念 Box: CSS布局的基本单位 Box是 CSS 布局的对象和基本单位, ...
- BFC浅析
1.定义 BFC(Block formatting context)即"块级格式化上下文".它是一个独⽴的渲染区域,只有Block-level box参与, 它规定了内部的Bloc ...
- BFC的概念、BFC触发方式、BFC作用介绍
一.BFC的概念 GFC——block fomatting context(中文译为块级格式化上下文) 二. 如何触发BFC 1. 设置 float 除 none 以外的值(left.right) 2 ...
- CSS3与页面布局学习总结(三)——BFC、定位、浮动、7种垂直居中方法
一.BFC与IFC 1.1.BFC与IFC概要 BFC(Block Formatting Context)即“块级格式化上下文”, IFC(Inline Formatting Context)即行内格 ...
随机推荐
- 【6折抢】戴尔i7新品Latitude高性能商用本
致敬拼搏成长中的企业 戴尔5月有钜惠! 买1赠1送同款,单台价格2500元 这波来自戴尔官网的致敬很走心 满足初级办公和高性能运算多重需求 限时折扣火热开抢! 新品 latitude 6折抢! 戴尔 ...
- 厉害了,Spring Cloud Alibaba 发布 GA 版本!
? 小马哥 & Josh Long ? 喜欢写一首诗一般的代码,更喜欢和你共同 code review,英雄的相惜,犹如时间沉淀下来的对话,历久方弥新. 相见如故,@杭州. 4 月 18 日, ...
- 5-Python操作MySQL步骤
1.引入模块 在py文件中引入pymysql模块 from pymysql import *(connect) 2.创建connection连接对象 conn=connect(参数列表) 参数host ...
- [CERC2017]Gambling Guide
题目 看起来非常随机游走,但是由于我们可以停在原地,所以变得不是非常一样 设\(f_x\)表示从\(x\)到\(n\)的期望距离 如果我们提前知道了\(f\),那么我们随机到了一张到\(y\)的车票, ...
- neo4j数据库迁移---------Neo4j数据库导入导出的方法
Neo4j数据进行备份.还原.迁移的操作时,首先要关闭neo4j; /usr/share/neo4j/bin neo4j stop 如果出现 Neo4j not running 出现这种情况, Neo ...
- Maven + Springboot + redis 配置
前言 刚进入到Java 开发的世界,对于小白Java的我来说,使用Maven + SpringBoot 的项目下启动redis: 第一步 本地安装Redis 服务 关于redis的教程链接 点击这里: ...
- Impala简介
- 获取linux性能数据
import reimport osimport sysimport jsonimport socketfrom urllib import request,parseimport urllibfro ...
- Apocalypse Someday
Apocalypse Someday 定义一个数是合法的,当且仅当中间出现至少一个连续的大于三个的6,求第x个合法的数,\(x\leq 50,000,000\) 解 首先,注意到求第几个,即想到试填法 ...
- 解决 php Call to undefined function shm_attach()
学习php 多进程的时候,运行脚本报错 Call to undefined function shm_attach() ,搜了一下,看到stack overflow 里面提示需要配置这些扩展 exte ...