深入理解css BFC 模型
如果要深入理解css布局的各种原理,要在重构页面做得心应手的话,那么你就必须先理解这玩意 “BFC” , BlockFormatting Context(块级格式化上下文);
这里,官方的定义写得有点难以理解,我就大概的讲一下,我个人的理解;
首先它是什么?
看了很多文章后,包括官方的解释,我个人将他理解如下:
它是css2提出来的,它是一个具有规定的渲染、定位等规则的块级元素(或者说成一个环境);大家都知道,盒子box,一个布局中,可以同时存在很多盒子boxes,而盒子只是容器而已,这也就是其不同之处,可以说成是其升级版,具有了一些规则和渲染方式之后就可以变成一个BFC,当然也只有块级元素能参与转化成BFC;
BFC内部的布局规则
1、内部的Box会在垂直方向,一个接一个地放置。
2、同一个BFC内,垂直方向盒子的上下margin会出现重叠
3、每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
4、子BFC的区域不会与float box重叠。
5、BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
6、计算BFC的高度时,浮动元素也参与计算(故也可以达到所谓的清除浮动的效果,只要将包裹层转变给BFC)
行,那么如何将一个块级元素转化成BFC?
官方给出了以下几种方式:
1、具有除了float:none的其它浮动属性值;
2、定位为absolute或者fixed;
3、display为inline-block, table-cell, table-caption, flex, inline-flex
4、overflow不为visible(除非该值已经传播到视口,如html body 会将overflow的值传播到视口,故此情况下,设置该属性不能建立bfc)
拥有以上随便一种属性就满足条件了;
来吧,重点来了!BFC的作用
Example-1 可以运用它来实现自适应两栏布局
<style>
*{
margin: 0;
} .div1 {
width: 100px;
height: 150px;
float: left;
background: yellow;
}
.div2 {
height: 200px;
background: green;
}
</style> <body>
<div class="div1"></div>
<div class="div2">演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字</div>
</body>
效果如下

到这里,验证了bfc布局规则的第三条:每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
接下来,我们要将div2转变成bfc,从而实现其自适应,而其原理就是:子BFC的区域不会与float box重叠,也即是div2为bfc后,其区域不会和左浮动的div1重叠;我们只需要给div2添加一个属性overflow:hidden,从而将其转化为bfc;
转变后效果如下:

即2个div不重叠了,并且,div2是自适应的
Example-2 边距坍塌margin collapse的解释
相信这个经典的小问题,大家都会遇到过,由于种种原因,可能你会觉得很烦,或者根本不理它了。事实上,这个问题是很好解释和解决的,只要你重视它;
上代码:
<style>
*{
margin: 0;
} .div1 {
background: yellow;
margin-bottom: 100px;
}
.div2 {
background: green;
margin-top: 100px;
}
</style>
<body>
<div class="div1">演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演</div>
<div class="div2">演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演示文字演</div>
</body>
效果如下

明明div1设置了下边距,div2设置了上边距,但是结果却只显示了1个边距,即重叠了;这里也验证了bfc的布局规则之同一个BFC内,垂直方向盒子的上下margin会出现重叠
那么这个现象,我的建议是其实跟本就没有必要去同时设置上下边距,布局时,对垂直方向上的div,设置统一向下的边距就好了,没必要同时上下设置;
当然,解决方法是有的,就是给div2 套一个包裹的div3,并且将其div3转化为bfc,具体如下:

效果:

为什么会这样呢?这里就是bfc的内部布局原理:BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。通俗的说,就是div3是一个bfc,而bfc不管具有一个特性,就是内部不管怎么样怎么设置都行,外部是不受任何影响的,因此,即使家里的div2多丑多乱,爸爸div3都会将他包容保密,不会将他告诉任何外面的人,这也就导致了div2的上边距存在于div3内,从而效果展示出来的是200px;
Example-3 清除内部浮动
<style>
*{
margin: 0;
box-sizing: border-box;
} ul{
width: 100%;
border: 5px solid red;
background: green;
}
li{
float: left;
margin-right: 10%;
height: 100px;
width: 20%;
background: yellow;
}
</style>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</body>
效果:

这个情况就不多废话了,浮动导致的外层div高度为0;
这个时候,我们除了用伪元素清除浮动,如下
.clearfix{
*zoom: 1;
}
.clearfix:after{
content: "";
display :table;
clear: both;
}
我们还能用bfc来清除浮动,解决这个问题:
将ul转化为一个bfc,如在ul加一个属性overflow: hidden;这个时候,就可以达到以下效果了

效果:

原理是 计算BFC的高度时,浮动元素也参与计算,即计算ul这个bfc高度时,里面的浮动li高度也会加入计算
为了彻底理解这个东西,我花了一天的时间,通过查阅资料,整理思路,动手实验,整理后写下来了这一篇文章,希望大家好好理解,这个东西,平时看不到,也不会去注意,但是如果你花点时间,好好的理解下,肯定是对你有所帮助的。
深入理解css BFC 模型的更多相关文章
- <转>HTML+CSS总结/深入理解CSS盒子模型
原文地址:http://www.chinaz.com/design/2010/1229/151993.shtml 前言:前阵子在做一个项目时,在页面布局方面遇到了一点小问题,于是上stackoverf ...
- 理解CSS盒子模型
概述 网页设计中常听的属性名:内容(content).填充(padding).边框(border).边界(margin),CSS盒子模型都具备这些属性,也主要是这些属性. 这些属性我们可以把它转移到我 ...
- 深入理解CSS盒子模型
在CSS中浮动.定位和盒子模型,都是很核心的东西,其中盒子模型是CSS很重要基石之一,感觉还是很有必要把CSS盒子模型相关知识更新一下...... CSS盒子模型<BoxModel>示意图 ...
- 深入理解CSS盒模型
如果你在面试的时候面试官让你谈谈对盒模型的理解,你是不是不知从何谈起.这种看似简单的题其实是最不好答的. 下面本文章将会从以下几个方面谈谈盒模型. 基本概念:标准模型 和IE模型 CSS如何设置这两种 ...
- 深入理解CSS盒模型(转)
转自:https://www.cnblogs.com/chengzp/p/cssbox.html 基本概念 盒模型的组成大家肯定都懂,由里向外content,padding,border,margin ...
- 深入理解CSS盒模型【转载】
下面本文章将会从以下几个方面谈谈盒模型. 基本概念:标准模型 和IE模型 CSS如何设置这两种模型 JS如何设置获取盒模型对应的宽和高 实例题(根据盒模型解释边距重叠) BFC(边距重叠解决方案) 基 ...
- 面试汇总——说一下CSS盒模型
本文是面试汇总分支——说一下CSS盒模型. 基本概念:W3C标准盒模型和IE盒模型 CSS如何设置这两种模型 JS如何获取盒模型对应的宽和高 根据盒模型解释边距重叠 BFC(边距重叠解决方案) 一. ...
- 聊聊css盒子模型
css盒子模型原理: 在网页设计中常听的属性名:内容(content).填充/内边距(padding).边框(border).外边距(margin), CSS盒子模式都具备这些属性. 这些属性我们可以 ...
- CSS盒模型的深度思考及BFC
本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. 题目:谈一谈你对CSS盒模型的认识 专业的面试,一定会问 CSS 盒模型 ...
随机推荐
- [Android] charles高级使用总结
reference to : http://blog.csdn.net/a910626/article/details/52823981 charles高级使用总结 网速模拟 点击菜单“Proxy→T ...
- unity播放视频
方法一: 1.用一个Quad(或者其他的)做屏幕,调整摄像机位置和它的大小,使它显示在你想要的区域 2.将视频拖入Unity,拖入,拖入,拖入:不是将视频直接copy到指定的文件夹中 3.将下面脚本挂 ...
- 浅谈Yii-admin的权限控制
说到CMS,最需要有的东西就是权限控制,特别是一些复杂的场景,多用户,多角色,多部门,子父级查看等等.最近在开发一个线下销售的东东,这个系统分为管理员端,省代端,客户端,门店端,销售端, 部门端,部门 ...
- TextView属性android:ellipsize="marquee"不生效的解决办法
最近自己在写自己的第一个app,过程中遇到了这个问题,查了不少帖子,经过尝试发现,这种问题一般分为两类: 1. TextView的Text值赋值后不更改,很多帖子上说如下写法就可以生效: <Te ...
- 【DWR系列04】- DWR配置详解
table { margin-left: 30px; width: 90%; border: 1px; border-collapse: collapse } img { border: 1px so ...
- oracle创建DBLINK
1.查看Global_name参数 show parameter global_name; 该参数为true时,你在本地建立的DBLINK的名称必须和远程的Global_name一致才行. 2.查看 ...
- JavaOO面向对象中的注意点(三)
1.接口 a.关键字:interface public interface Serviceable{ //TODO } b.属性:只能是 公共 静态 常量 属性--就算不写这三个关键字,也是默认这种情 ...
- selenium使用笔记(三)——元素定位
selenium进行自动化测试的一个很重要的东西那就是元素定位,如果元素都没法定位就无法操作它,也就无法进行自动化测试了.网上对于元素定位有很多的介绍,很详细很详细的,但是依然有很多新手总是会遇到无法 ...
- Linux学习笔记(8)-exec族函数
昨天学习了Linux下的进程创建,创建一个进程的方法极为简单,只需要调用fork函数就可以创建出一个进程,但是-- 介绍fork()函数的时候提到,在创建进程后,子进程与父进程有相同的代码空间,执行的 ...
- ASP.NET 给作为隐藏域的TextBox赋值之后提交表单,无响应?
操作步骤: 给页面隐藏TextBox赋值,然后触发ASP.NET change事件,调用ASP.NET后台方法,调用后执行客户端脚本this.RegisterClientScriptBlock(Dat ...