在讲 BFC 以前,咱们先来了解一下常见的定位方案,定位方案是控制元素的布局,有三种常见方案:css
在普通流中,元素按照其在 HTML 中的前后位置至上而下布局,在这个过程当中,行内元素水平排列,直到当行被占满而后换行,块级元素则会被渲染为完整的一个新行,除非另外指定,不然全部元素默认都是普通流定位,也能够说,普通流中元素的位置由该元素在 HTML 文档中的位置决定。html
在浮动布局中,元素首先按照普通流的位置出现,而后根据浮动的方向尽量的向左边或右边偏移,其效果与印刷排版中的文本环绕类似。布局
在绝对定位布局中,元素会总体脱离普通流,所以绝对定位元素不会对其兄弟元素形成影响,而元素具体的位置由绝对定位的坐标决定。post
Formatting context(格式化上下文) 是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,而且有一套渲染规则,它决定了其子元素将如何定位,以及和其余元素的关系和相互做用。flex
那么 BFC 是什么呢?spa
BFC 即 Block Formatting Contexts (块级格式化上下文),它属于上述定位方案的普通流。3d
具备 BFC 特性的元素能够看做是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,而且 BFC 具备普通容器所没有的一些特性。code
通俗一点来说,能够把 BFC 理解为一个封闭的大箱子,箱子内部的元素不管如何翻江倒海,都不会影响到外部。orm
只要元素知足下面任一条件便可触发 BFC 特性:cdn
咱们在布局时常常会遇到这个问题:对子元素设置浮动后,父元素会发生高度塌陷,也就是父元素的高度变为0。解决这个问题,只须要把父元素变成一个BFC就好了。经常使用的办法是给父元素设置overflow:hidden。
<style> .box1{ width:100px; height:100px; float:left; border: 1px solid #000; } .box2{ width:100px; height:100px; float:left; border: 1px solid #000; } .box{ background:yellow } </style>
<body>
<div class="box">
<div class="box1"></div>
<div class="box2"></div>
</div>
</body>
复制代码
因为容器内两个div元素浮动,脱离了文档流,父容器内容宽度为零(即发生高度塌陷),未能将子元素包裹住。解决这个问题,只须要把把父元素变成一个BFC就好了。经常使用的办法是给父元素设置overflow:hidden。
在CSS当中,相邻的两个盒子的外边距能够结合成一个单独的外边距。这种合并外边距的方式被称为折叠,而且于是所结合成的外边距称为折叠外边距。
折叠的结果:
这个一样能够利用BFC解决。 若是想要避免外边距的重叠,能够将其放在不一样的 BFC 容器中。
<style> p{ color: #fff; background: #888; width: 200px; line-height: 100px; text-align:center; margin: 100px; } </style>
<body>
<p>ABC</p>
<p>abc</p>
</body>
复制代码
上面例中两个P元素之间距离本该为200px,然而实际上只有100px,发生了margin重叠。遇到这种情形,咱们如何处理? 只须要在p外面包裹一层容器,并触发该容器生成一个BFC。那么两个P便不属于同一个BFC,就不会发生margin重叠了。
<style> p{ color: #fff; background: #888; width: 200px; line-height: 100px; text-align:center; margin: 100px; } .wrap{ overflow:hidden; } </style>
<body>
<p>ABC</p>
<div class="wrap">
<p>abc</p>
</div>
</body>
复制代码
<style> .box{ width:100px; height:100px; background:#ccc; } .wrap { background:yellow; } .wrap h1{ background:pink; margin:40px; } </style>
<body>
<div class="box">box</div>
<div class="wrap">
<h1>h1</h1>
</div>
</body>
复制代码
上图wrap元素与h1元素之间l理论上本该有个40px的上下margin值,然而实际上父子元素并无存在margin值,与此同时,两个div元素的间距为40px。遇到这种情形,咱们如何处理? 处理方法其实有不少,**在wrap元素中添加:overflow:hidden;或者overflow:auto;使其父元素造成一个BFC;也能够在wrap元素中添加border:1px solid;或是padding:1px;**这些均可以有效解决父子元素margin重叠问题。
这个方法能够用来实现两列自适应布局,也就是左边的宽度固定,右边的宽度自适应。若是咱们改变文字的大小或者左边浮动元素的大小,两栏布局的结构依然没有改变!
<style> *{ margin: 0; padding: 0; } .box { width:300px; border: 1px solid #000; } .img { float: left; } .info { background: #f1f1f1; color: #222; } </style>
<body>
<div class="box">
<img src="03.jpg" alt="" class="img">
<p class="info">信息信息信息信息信息信息</p>
</div>
</body>
复制代码
通常状况下,它是这样的
可是当文字多了之后...
显然,这是文字受到了图片浮动的影响。固然,若是你想作文本绕排的效果,浮动是不二之选。不过在这里,这显然不是咱们想要的。此时咱们能够为P元素的内容创建一个BFC,让其内容消除对外界浮动元素的影响。给文字加上overflow:hidden
两栏布局就完成了。咱们改变图片的大小:
两栏布局的结构依然没有改变,如此就实现了两栏自适应布局。