hasLayout与Block formatting contexts的学习(下)
BFC布局规则:
- 内部的Box会在垂直方向,一个接一个地放置。
- Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
- 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
- BFC的区域不会与float box重叠。
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 计算BFC的高度时,浮动元素也参与计算。
- 在CSS3中,对这个概念做了改动:http://www.w3.org/TR/css3-box/#block-level0
在CSS3中,将BFC 叫做 flow root。
简单示例:
1.自适应两栏布局
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BFC</title>
<style>
body{
width:350px;
position:relative;
}
div.sidebar{
float:left;
width:100px;
height:200px;
background-color:#9deaf1;
}
div.main{
height:300px;
background-color:#5dc2f6;
}
</style>
</head>
<body>
<div class="sidebar"></div>
<div class="main"></div>
</body>
</html>
页面效果图:
上述示例,正好反映了BFC布局规则:每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
所以,sidebar虽然存在浮动,但main的左边依然与包含块的左边相接触。
2.BFC的区域不会与float box重叠。示例如下:
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BFC</title>
<style>
body{
width:350px;
position:relative;
}
div.sidebar{
float:left;
width:100px;
height:200px;
background-color:#9deaf1;
}
div.main{
height:300px;
background-color:#5dc2f6;
overflow:hidden;
}
</style>
</head>
<body>
<div class="sidebar"></div>
<div class="main"></div>
</body>
</html>
页面效果图:
通过overflow:hidden;触发main的BFC,main区域没有与float的sidebar重叠。说明了BFC的区域不会与float box重叠。
3.计算BFC的高度时,浮动元素也参与计算。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BFC</title>
<style>
div.wrapper{
width:300px;
border:2px solid #5dc2f6;
}
div.box{
width:100px;
height:200px;
background-color:#9deaf1;
border:2px solid #5dc2f6;
float:left;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="box"></div>
<div class="box"></div>
</div>
</body>
</html>
页面效果图:
我们通过
div.wrapper{
width:300px;
border:2px solid #5dc2f6;
overflow:hidden;
}
overflow:hidden; 触发wrapper的BFC,
清除box的浮动带来的影响,得到的页面效果图如下:
因此说明:计算BFC的高度时,浮动元素也参与计算。
4.清除垂直边距重叠
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BFC</title>
<style>
div.box{
width:100px;
height:100px;
background-color:#9deaf1;
border:2px solid #5dc2f6;
}
div.m50{
margin-bottom:50px;
}
div.m100{
margin-top:100px;
}
</style>
</head>
<body>
<div class="box m50"></div>
<div class="box m100"></div>
</body>
</html>
页面效果图如下:
如图所示,Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。所以,两个div的垂直距离变成了100px,而不是150px了。
如果我们给第二个div套上一层wrapper,并且触发外层的BFC,那么两个div就不是同一个BFC的两个相邻的Box了,而是变成两个独立的BFC。
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BFC</title>
<style>
div.box{
width:100px;
height:100px;
background-color:#9deaf1;
border:2px solid #5dc2f6;
}
div.wrapper{
overflow:hidden;
}
div.m50{
margin-bottom:50px;
}
div.m100{
margin-top:100px;
}
</style>
</head>
<body>
<div class="box m50"></div>
<div class="wrapper">
<div class="box m100"></div>
</div>
</body>
</html>
页面效果图如下:
垂直边距不再重叠,不是100px,而是150px了。
总结
以上事例都证明了:BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。 因为BFC内部的元素和外部的元素绝对不会互相影响,因此, 当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,所以BFC通过改变自己的宽度,实现不与浮动box有重叠。同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度。避免margin重叠也是这样的一个道理。
hasLayout与Block formatting contexts的实例分析
一. 在触发 hasLayout 的元素和创建了 Block Formatting Contexts 的元素中,浮动元素参与高度的计算
情况1:没有创建 Block formatting contexts 的块级非替换元素,触发了 IE 的 hasLayout。
分析以下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hasLayout 和 BFC</title>
<style>
div.wrapper{
width:300px;
}
div#container{
background-color:#9deaf1;
zoom:1;
}
span#span1{
background-color:#5dc2f6;
}
div#div1{
width:150px;
height:50px;
background-color:#0576b0;
}
div#div2{
float:left;
background-color:#4dd5b3;
}
</style>
</head>
<body>
<div class="wrapper">
<div id="container">
<span id="span1">simple text</span>
<div id="div1">in flow</div>
<div id="div2">float:left</div>
</div>
</div>
</body>
</html>
- container 没有创建 Block formatting contexts。
- container 的 'zoom:1'设置,是为了触发 IE 中的 hasLayout;
- container 的高度值为 auto,并且 'overflow' 的值为默认的 'visible';
- span1是一个行内元素, div1 是一个处于普通流中的块元素;
- div2 是一个浮动的块级元素。
根据 CSS2.1 规范第 10.6.3部分的高度计算规则,在进行普通流中的块级非替换元素的高度计算时,浮动子元素不参与计算。
所以,在进行 container 高度计算时,只受 span1 和 div1的影响,应该是它们两个的高度之和,所以最终container 的高度不包括div2的高度。
页面效果图在各浏览器的效果如下:
IE6 IE7:
IE8 Firefox Chrome Safari Opera:
当去掉container的zoom:1;各浏览器表现一致:
情况2:创建了 BFC的块级非替换元素,未触发 IE 的 hasLayout。
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hasLayout 和 BFC</title>
<style>
div.wrapper{
width:300px;
}
div#container{
background-color:#9deaf1;
overflow:hidden;
}
span#span1{
background-color:#5dc2f6;
}
div#div1{
width:150px;
height:50px;
background-color:#0576b0;
}
div#div2{
float:left;
background-color:#4dd5b3;
}
</style>
</head>
<body>
<div class="wrapper">
<div id="container">
<span id="span1">simple text</span>
<div id="div1">in flow</div>
<div id="div2">float:left</div>
</div>
</div>
</body>
</html>
- container 的 ‘overflow:hidden;’ 创建了BFC;
- container 的 ‘overflow:hidden;’,在 IE6 中未触发 hasLayout,但在 IE7中触发了 hasLayout;
- container 的高度值为 ‘auto’;
- span1是一个行内元素,div1是一个处于普通流中的块元素;
- div2是一个浮动的块级元素。
页面效果图如下:
IE6:
IE7/IE8/Firefox/Chrome/Safari/Opera
可见,只要 container 创建了 BFC,其浮动子元素就会参与其高度计算(IE7是由于触发了hasLayout 导致与其它浏览器的效果相同)。
二.与浮动元素相邻的、触发了 hasLayout 的元素或创建了 BFC 的元素,都不能与浮动元素相互覆盖。
与浮动元素相邻的、触发了 hasLayout 的元素或创建了 Block formatting contexts的元素,都不能与浮动元素相互覆盖。如果浮动元素的两侧有足够的空间放置该元素,则元素会紧邻浮动元素放置,必要时,该元素的宽度将会被压缩。否则它们可能会定位到浮动元素的下方。
情况1:没有创建BFC的块级非替换元素,触发了 IE 的 hasLayout。
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hasLayout 和 BFC</title>
<style>
div#container{
border:2px solid #ddd;
width:300px;
height:150px;
background:url("http://images0.cnblogs.com/
blog2015/790006/201508/041827351894332.png") repeat;
}
div#div1{
width:100px;
height:100px;
background-color:#9deaf1;
float:left;
filter:alpha("opacity=50");
opacity: 0.5;
}
div#div2{
background-color:green;
zoom:1;
}
</style>
</head>
<body>
<div id="container">
<div id="div1">
Float Block
</div>
<div id="div2">
怀才就象怀孕,时间久了会让人看出来。
</div>
</div>
</body>
</html>
IE6:
IE7/IE8
Firefox/Chrome/Safari/Opera
根据 CSS 2.1 9.5 Floats 中的描述,浮动元素会覆盖普通流中的块容器。所以,div2 应该有一部分被 div1 覆盖。
情况2:创建了 BFC的块级非替换元素,未触发 IE 的 hasLayout。
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hasLayout 和 BFC</title>
<style>
div#container{
border:2px solid #ddd;
width:300px;
height:150px;
background:url("http://images0.cnblogs.com/
blog2015/790006/201508/041827351894332.png") repeat;
}
div#div1{
width:100px;
height:100px;
background-color:#9deaf1;
float:left;
filter:alpha("opacity=50");
opacity: 0.5;
}
div#div2{
background-color:green;
overflow:hidden;
}
</style>
</head>
<body>
<div id="container">
<div id="div1">
Float Block
</div>
<div id="div2">
怀才就象怀孕,时间久了会让人看出来。
</div>
</div>
</body>
</html>
Firefox/Chrome/Safari/Opera:
IE6:
IE7/IE8
- div1 是一个浮动元素,背景是50%的透明
- div2 的 ‘overflow:hidden;’ 在 IE6 中未触发 hasLayout,但在 IE7 中触发了 hasLayout。
根据 CSS 2.1 9.5 Floats 中的描述,创建了BFC的元素不能与浮动元素重叠, 所以,div2 应该有一部分被 div1 覆盖。
三. 触发 hasLayout 的元素和创建了 BFC的元素不会与它们的子元素发生外边距折叠
情况1:没有生成BFC的块级非替换元素,触发了 IE 的 hasLayout。
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hasLayout和BFC</title>
<style>
div.box{
width:100px;
height:100px;
background-color:#9deaf1;
border:2px solid #5dc2f6;
}
div.wrapper{
zoom:1;
}
div.m50{
margin-bottom:50px;
}
div.m100{
margin-top:100px;
}
</style>
</head>
<body>
<div class="box m50"></div>
<div class="wrapper">
<div class="box m100"></div>
</div>
</body>
</html>
根据 CSS 2.1 8.3.1 Collapsing margins 第一条,两个相邻的普通流中的块框在垂直位置的空白边会发生折叠现象。
通过zoom:1;在IE中触发了hasLayout,所以,垂直边距不重叠,为150px。
而BFC未触发,所以垂直边距重叠,为100px;
IE6/IE7:
IE8/Firefox/Chrome/Safari/Opera:
情况2:生成 BFC的块级非替换元素,未触发 IE 的 hasLayout。
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BFC</title>
<style>
div.box{
width:100px;
height:100px;
background-color:#9deaf1;
border:2px solid #5dc2f6;
}
div.wrapper{
overflow:hidden;
}
div.m50{
margin-bottom:50px;
}
div.m100{
margin-top:100px;
}
</style>
</head>
<body>
<div class="box m50"></div>
<div class="wrapper">
<div class="box m100"></div>
</div>
</body>
</html>
IE6:
IE7/IE8/Firefox/Chrome/Safari/Opera:
IE7此时触发了hasLayout,但IE6没有触发hasLayout。
hasLayout 和 BFC 的异同及可能产生的问题
区别
- 在 IE8之前的版本中,没有规范中提及的 Block formatting contexts 和 Inline formatting contexts概念,而是用 hasLayout 来达到相似的目的。
- 在 IE 中可通过设置 ‘width’、’height’、’min-width’、’min-height’、’max-width’、’max-height’、 ‘zoom’、’writing-mode’ 来触发 hasLayout,而这些特性值的设置不能够使元素创建 BFC。
- 在 IE 中很多元素默认就是拥有布局的,如 IPUNT, BUTTON, SELECT, TEXTAREA 等,但是这些元素在标准中会形成 Inline formatting contexts。
共同点
- 两者都是决定了对内容如何定位及大小计算的规则。
- 两者都决定了与其他元素的相互作用的规则。
- ‘table-cell’ 和 ‘table-caption’ 既是 hasLayout 的元素,又是可以创建 BFC 的元素。
- 浮动元素,绝对定位元素,inline-block 元素以及除 ‘visible’ 外任意值的 overflow(IE7) 在 IE 中可以触发 hasLayout,同时在标准中,又可以创建BFC。
可能产生的兼容性问题:
由于 hasLayout 和 BFC是对一类事物的不同理解,并且他们的启用条件不尽相同,因此如果一个元素设计时,在 IE 早期版本中触发了 hasLayout ,但在其他浏览器中又没有创建BFC,或者相反,一个元素在 IE 早期版本中没有触发 hasLayout ,在其他浏览器中却创建了 BFC(如设置了 ‘overflow:hidden’ ),将导致页面布局的重大差异。
解决方案
仅当一个元素即在 IE 早期版本中触发了 hasLayout,又在其他浏览器中创建了BFC时,才能避免上述问题的发生。即同时启用上述两者以保证各浏览器的兼容,或者相反,两者皆不启用。
使元素即生成了BFC,又触发了 hasLayout
对于触发 hasLayout 的元素,通过 CSS 设置,使它产生BFC;
生成 BFC但是没有触发 hasLayout 的元素,通过设置 ‘zoom:1’,使其触发 hasLayout。
使元素即没有触发 hasLayout,又没有创建 BFC。
如有错误或者不足的地方,还望指正!----妙瞳
文章参考资料:
http://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.html
http://w3help.org/zh-cn/causes/RM8002
hasLayout与Block formatting contexts的学习(下)的更多相关文章
- hasLayout与Block formatting contexts的学习(上)
hasLayout与Block formatting contexts的学习 @(css BFC)[IE hasLayout|妙瞳] hasLayout是什么? haslayout 是Windows ...
- hasLayout && Block Formatting Contexts
转自:http://www.smallni.com/haslayout-block-formatting-contexts/ 因为本人脑子不好使,自己打印出了一张hasLayout和Block For ...
- margin折叠及hasLayout && Block Formatting Contexts
margin折叠的产生有几个条件: 这些margin都处于普通流中,并在同一个BFC中: 这些margin没有被非空内容.padding.border 或 clear 分隔开: 这些margin在垂直 ...
- 详说 Block Formatting Contexts (块级格式化上下文)
在上文<详说清除浮动>中,Kayo 较为详细地介绍了 BFC ,也就是本文的主角 Block Formatting Contexts (块级格式化上下文),本文会基于上文关于 BFC 的部 ...
- Block Formatting Contexts (块级格式化上下文) 使用参考
转自:http://kayosite.com/block-formatting-contexts-in-detail.html 在上文<详说清除浮动>中,Kayo 较为详细地介绍了 BFC ...
- Block Formatting Contexts (块级格式化上下文) 详解
最近在学习BootStrap框架,发现里面清除浮动的类 .clearfix 跟平时自己用的不太一样.它的样式是这样的: .clearfix:before { content: " ...
- 我们常用,却容易忽视——CSS的BFC(Block formatting contexts)
BFC——一个我们容易忽视掉的布局神器 今天给大家说说BFC这个概念,在说概念前,先给大家看个例子: 首先,定义三个div块元素 效果: 我们发现,块级元素的排列顺序是从上往下,一块接着一块,在w ...
- BFC 详说 Block Formatting Contexts (块级格式化上下文)
定位方案是控制元素的布局,在 CSS 2.1 中,有三种定位方案——普通流 (Normal Flow) .浮动 (Floats) 和绝对定位 (Absolute Positioning) ,下面分别对 ...
- 块级格式化上下文( Block formatting contexts)
那么如何触发BFC呢? float 除了none以外的值 overflow 除了visible 以外的值(hidden,auto,scroll ) display (table-cell,table- ...
随机推荐
- Python PIL创建文字图片
PIL库中包含了很多模块,恰当地利用这些模块可以做许多图像处理方面的工作. 下面是我用来生成字母或字符串测试图片而写的类及测试代码. 主要用到的模块: PIL.Image,PIL.ImageDraw, ...
- uva 12296 Pieces and Discs
题意: 有个矩形,左下角(0,0),左上角(L,W). 思路: 除了圆盘之外,本题的输入也是个PSLG,因此可以按照前面叙述的算法求出各个区域:只需把线段视为直线,用切割凸多边形的方法 :每次读入线段 ...
- mvc5经典教程再补充。。
转自:http://www.cnblogs.com/powertoolsteam/p/3656203.html ASP.NET MVC 5 - 查询Details和Delete方法 在这部分教程中 ...
- 一切不以用户为中心的O2O 都是耍流氓
今天去万达广场逛街,手机搜了下附近的Wifi,发现有万达的免费Wifi,想起前些日子网上说万达要做O2O的试运营,于是尝试连接了下,结果弹出页面,要输入手机号,然后发送验证码才能登陆,结果输入手机号, ...
- 基于memcached的单机轻量级通用缓存库minicached的实现
一.前言 之前拜读过淘宝子柳的<淘宝技术这十年>之大作,深知缓存技术在系统优化中起着一个举足轻重的作用.无论是文件系统静态文件,数据库的访问,乃至网络数据的请求,只要是与内存访问速度相差较 ...
- 第十三章、学习 Shell Scripts 简单的 shell script 练习
简单的 shell script 练习 简单范例 对谈式脚本:变量内容由使用者决定 [root@www scripts]# vi sh02.sh #!/bin/bash # Program: # Us ...
- VS项目重命名工具
VS项目重命名工具 VS项目整体重命名工具 不再为项目重命名和修改命名空间而烦恼,简单几个字,但是开发加上测试大量项目,前前后后竟然跨越了1个月,汗...不过真正的开发时间可能2-3天的样子. 一. ...
- JavaScript 要点(十四)HTML DOM 元素(节点)
A.创建新的 HTML 元素 如需向 HTML DOM 添加新元素,必须首先创建该元素(元素节点),然后向一个已存在的元素追加该元素. <div id="div1"> ...
- java异步任务处理
1.场景 最近做项目的时候遇到了一个小问题:从前台提交到服务端A,A调用服务端B处理超时,原因是前端一次请求往db插1万数据,插完之后会去清理缓存.发送消息. 服务端的有三个操作 a.插DB b.清理 ...
- python学习(5)
python(5)5.1 模块:每个.py文件就是一个模块,多个模块可以放在一个包中,而多个包可以放在更大的包中.表示包A中的asd.py可以这样写:A.asd sys模块:它是python的内建模块 ...