原文连接: Fyerl's Blogcss
提及 BFC 其实有点像闭包在大多数人印象中的感受,平时都用过,但在不了解定义的状况下大多数人却又不知道这就是 BFC。之因此会想了解下什么是 BFC,是由于前些日的一个简单且常见的排版问题html
HTML 代码结构以下css3
<div class="form-item"> <span class="label">登陆名</span> <div class="content"> <input type="text" placeholder="请输入登陆名"> </div> </div>
label 的宽度是自适应的,content 需填充满此行剩余的区域。常规方法经过 flex 布局,很简单闭包
.form-item { display: flex; } .content { flex: 1; }
可是 flex 的兼容性仍是不够向下的,因而搜索了一下,获得了这么个方案app
.label { float: left; } .content { overflow: hidden; }
label 给了个 float 能够理解,但 content 写了一个 overflow: hidden 是什么意思?实则这里的 content 就造成了一个 BFC,因此仍是先回到 BFC 这个概念上布局
BFC 即(Block Format Context)块级格式化范围,是 CSS2.1 中用于规定块级盒子的渲染布局方式
以上条件知足任一便会触发建立一个 BFC,同时也能够看出这些属性的设置会产生一些额外的效果,好比仅仅是想触发 BFC,却使用了 overflow: scroll 致使元素出现了滚动条,因此具体使用哪一种方式触发 BFC,仍是须要结合实际的业务场景flex
<style> .block { background: #eee; overflow: hidden; } .item { height: 44px; margin: 12px 0; background: #666; } </style> <body> <div class="block"> <p class="item"></p> <p class="item"></p> </div> </body>
如上,两个 item 均存在上、下 margin,理想状况下,两个 item 之间间距应是 24px,但结果只有 12px,这即是外边距折叠,兄弟元素外边距不一样时,取最大值。这种行为只存在于兄弟元素在同一 BFC 下这种情形。若想消除外边距折叠,对上述代码作一些改造,使兄弟元素存在于不一样 BFC 之中便可spa
<style> .block { background: #eee; overflow: hidden; } .item-wrapper { overflow: hidden; } .item { height: 44px; margin: 12px 0; background: #666; } </style> <body> <div class="block"> <div class="item-wrapper"> <p class="item"></p> </div> <div class="item-wrapper"> <p class="item"></p> </div> </div> </body>
此时 item-wrapper 便造成了一个 BFC,解决了外边距折叠问题。相信你们遇到这种状况习觉得常地会加一层外层元素再给个 overflow: hidden,但为何 overflow: hidden 就能消除折叠,其实背后是 BFC 的原理3d
<style> .block { padding: 12px; background: #eee; } .item { float: left; height: 44px; width: 100%; background: #666; } </style> <body> <div class="block"> <p class="item"></p> </div> </body>
此时内部 item 已脱离常规文档流,父元素没法被子元素撑起。若须要父元素包裹住子元素,一是经过常见的 clearfix 方案,二就是同过构造父元素为 BFC,也就是经过你们熟悉的 overflow: hidden,这里涉及到的特性就是 BFC 能包裹住本身的后代浮动元素code
<style> .block { padding: 12px; background: #eee; overflow: hidden; } .item { float: left; height: 44px; width: 100%; background: #666; } </style> <body> <div class="block"> <p class="item"></p> </div> </body>
<style> .block { padding: 12px; background: #eee; overflow: hidden; } .label { float: left; height: 44px; width: 200px; background: #999; margin-right: 12px; } .content { height: 68px; background: #666; } </style> <body> <div class="block"> <p class="label"></p> <p class="content"></p> </div> </body>
回到最开始的布局问题上了,此时 label 浮动于 content 之上,若是 content 内填充了其余元素,当 content 高度大于 label 必定高度时 content 内元素会被 label 覆盖或文本元素会围绕着 label。以下图,固然不但愿右侧地址的第二行会从最左边开始
此时一行代码构造 content 为 BFC,问题便解决了
<style> .block { padding: 12px; background: #eee; overflow: hidden; } .label { float: left; height: 44px; width: 200px; background: #999; margin-right: 12px; } .content { height: 68px; background: #666; overflow: hidden; } </style> <body> <div class="block"> <p class="label"></p> <p class="content"></p> </div> </body>
本文对 BFC 稍做梳理,望对代码中那些莫名的 overflow: hidden 的理解有所帮助。上文提到的 overflow: flow-root 能够看下大漠的这篇文章《flow-root》