深入理解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 盒模型 ...
随机推荐
- sh 测试网段在线主机
yum install nmap nmap -sP 192.168.21.1/24 查看网段在线主机 grep -vwf file1 file2 文件内容比较 #!/bin/bash # day=` ...
- 经受时间沉淀的15 个 Android 通用流行框架大全
1. 缓存 名称描述 DiskLruCache: Java实现基于LRU的磁盘缓存 2.图片加载 名称描述 Android Universal Image Loader 一个强大的加载,缓存,展 ...
- Docker上ubuntu新建用户的网络访问不通问题
背景 作为一个生命不息,折腾不止的码农.各种操作系统被我不知道搞崩了多少次,无数个夜晚连夜抢修数据,重装系统,那个累啊!! Option 1:备份.数据可以备份,配置可以备份,安装包可以备份.但是安装 ...
- 【DWR系列04】- DWR配置详解
table { margin-left: 30px; width: 90%; border: 1px; border-collapse: collapse } img { border: 1px so ...
- Linux中SysRq的使用(魔术键)
转:http://www.chinaunix.net/old_jh/4/902287.html 魔术键:Linux Magic System Request Key Hacks 当Linux 系统不能 ...
- PROC 文件系统调节参数介绍(netstat -us)
转自:http://www.cnblogs.com/super-king/p/3296333.html /proc/net/* snmp文件 Ip: ip项 Forwarding : 是 ...
- java web系统中时间比sql server中的日期少2天的解决办法
系统环境 jdk:1.7 数据库:sql server 2008 问题描述 升级1.7之后查询出来的日期就比数据库中的少2天,降回1.6版本的jdk就正常了. 问题原因及解决办法 国内网站有很多不靠谱 ...
- NetMQ(三): 发布订阅模式 Publisher-Subscriber
ZeroMQ系列 之NetMQ 一:zeromq简介 二:NetMQ 请求响应模式 Request-Reply 三:NetMQ 发布订阅模式 Publisher-Subscriber 四:NetMQ ...
- conda安装包
前面讲了有关conda改变镜像提高安装速度,这里来解决很多实用C写的酷,在Windows下不好安装的解决方案 1. 寻找wheel预编译文件 没有的话 2.使用conda命令安装 没有该包的话 3.实 ...
- Mac Android开发环境变量的配置(java、sdk、ndk、gradle)
1.打开terminal 2.然后输入 vi .bash_profile 后按"e"进入编辑模式 3.输入想要配置的环境变量(Java.sdk.ndk.gradle): expor ...