前言

经常在面试中被问到“如何清除浮动?”、“为什么 overflow: hidden 可以清除浮动?”等等比较基础的问题。虽然这些题目案在各种写面试题的文章中都有提供答案,但这种教科书式的问答肯定不是我们的目的,与其记住答案不如彻底掌握其核心原理——块级格式化上下文(BFC)

这篇文章主要就是彻底分析清楚BFC原理、总结BFC经典场景中的用法,最后再实践分析解决布局中常遇到的问题。

本文首发自迪诺笔记,转载请注明出处

一、BFC作用

  • 清除浮动:BFC会包含创建它的元素内部的所有内容(包含浮动元素)
  • 外边距折叠:解决同一BFC容器中的相邻元素间的外边距折叠问题
  • 左图右文布局:利用浮动元产生BFC以及BFC之间不会互相覆盖实现左图右文布局

以上BFC的作用可以当做一次检验,思考下如何实现,本文后面将会有原理以及实现的讲解

二、如何产生BFC

名称如何产生备注html根元素html元素本身就是一个BFC元素记住就好,body元素不是BFC浮动元素元素的float属性不是none常用绝对定位元素position属性为absolute或fixed常用行内块元素display属性为inline-block常用表格元素表格元素默认display属性即是BFC表格单元格、表格标题也是弹性元素display属性为flex或inline-flex元素的直接子元素非常重要(flex布局常用)网格元素display属性为grid或inline-grid元素的直接子元素新特性用得少多列容器元素的column-count或column-width不为auto,包括 column-count为1新特性用得少overflow属性overflow属性值不为visible的元素常用oveflfow:visibledisplay属性display属性值为flow-root的元素,flow-root: 一个新的display属性的值,它可以创建无副作用的BFC用得少contain属性contain属性值为layout、content、paint的元素用得少

总结成一句话:凡脱离文档流都可以产生BFC

三、BFC原理

三种文档定位方式

在讲BFC的原理之前先看看html文档的三种定位方式

普通流

在普通流中,元素按照其在HTML中的先后位置自上而下布局,在这个过程中,行内元素水平排列,直到当行被占满然后换行,块级元素则会被渲染为完整的一个新行,除非另外指定,否则所有元素默认都是普通流定位,也就是说普通流中元素的位置由该元素在HTML文档中的位置决定。

浮动

在浮动定位中,元素首先按照普通流的位置出现,然后根据浮动的方向尽可能的向左边或右边偏移,其效果与印刷排版中的文本环绕相似。

绝对定位

在绝对定位中,元素会整体脱离普通流,因此绝对定位元素不会对其兄弟元素造成影响,而元素具体的位置由绝对定位的坐标决定。

BFC产生作用的原因

其实BFC是上面三种布局方式中的普通流,BFC会产生一个独立的容器,该容器内部的元素不会在布局上影响到外部的元素,在外部的普通流看来它和其他普通流元素无差别,文档最终会按照上面说的普通流计算布局。

BFC的注意事项

块格式化上下文对浮动定位与清除浮动都很重要。浮动定位和清除浮动时只会应用于同一个BFC内的元素。 浮动不会影响其它BFC中元素的布局,而清除浮动只能清除同一BFC中在它前面的元素的浮动。 外边距折叠也只会发生在属于同一BFC的块级元素之间。

四、BFC常见用法

为了更好的理解BFC,我们先看看下面这些常见的用法。

清除浮动防止高度塌陷

按照上面三种定位方式中说的,浮动元素会脱离普通文档流,导致外部元素的高度计算不包括浮动元素本身高度,形成高度塌陷。

<div class="container"><div class="box box1"></div>
</div>
.box {width: 20px;height: 50px;float: left; // 脱离了文档流形成了一个BFCborder: 4px solid green;
}

采用上述产生BFC元素的方法之一使外层元素产生BFC,可以防止元素高度塌陷。

.container {overflow: hidden; // 外层容器产生BFC
}

处理外边距折叠的问题

在普通文档流中,元素(非BFC元素)的外边距margin会自动折叠,产生如下现象。

<div class="container"><div class="box box1 m20"></div><div class="box box2 m20"></div>
</div>
.m20 {margin: 20px;
}
.box {border: 1px solid green;
}

这个是html的特性不算bug,但是我们更希望margin不产生折叠效果,通过利用BFC元素之间的外边距不会折叠的特性来实现。

<div class="container"><div class="box box1 m20"></div><div class="box box2 m20"></div>
</div>
.m20 {margin: 20px;
}
.box {overflow: hidden; // 使得两个box成为BFC元素border: 4px solid green;
}

使两个box形成BFC或者分别用两个BFC包裹box,然后形成的两个BFC之间的外边距不会折叠,修复后效果如下图。

五、扩展一下

存在块级格式化上下文BFC,则对应存在内联格式化上下文IFC、网格格式化上下文GFC、自适应格式化上下文FFC,这些都可以统称为格式化上下文。

IFC

内联格式化上下文,IFC 的 line box(线框)高度由其包含行内元素中最高的实际高度计算而来,不受到竖直方向的 padding、margin 影响。

当在内联元素中插入块级元素会产生什么效果呢?在内联元素中插入位置前后的内联元素各自形成一个IFC,然后按照普通文档流进行布局,效果如下图。

GFC

网格布局格式化上下文(display: grid

FFC

自适应格式化上下文(display: flex

六、常见问题分析

为什么overflow: hidden可以清除浮动?

overflow: hidden使得外层元素产生了一个BFC,BFC的高度计算包含其内部的浮动元素,从而达到清除浮动效果

<div style="border: 5px solid #6EBD91; overflow: hidden;"><div style="float: left; border: 5px solid #F4D491;">Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus, maxime fuga assumenda excepturi, exercitationem rerum quae voluptates sunt perspiciatis cupiditate sed itaque officia, placeat minus iure quod expedita earum nam.Eum aliquam totam iure mollitia deserunt, minus repellendus. Harum ullam tenetur, impedit aliquam nobis ut dignissimos eligendi, expedita illum iste esse odio ab quos explicabo, odit architecto. Tempora, hic facilis?</div>
</div>

效果如下:

分析过程

外层overflow: hidden的元素产生了一个BFC,本身float: left的元素也产生了一个BFC,外层BFC进行尺寸计算时包含内层BFC尺寸。

常用的clearfix清除浮动如何实现?

// 采用after伪元素实现
.clearfix::after {content: " ";display: block;height: 0;clear: both;
}
// 兼容IE6
.clearfix {zoom: 1;
}

.clearfix类绑定到外层非浮动元素上,clear: both属性确保外层元素在进行高度计算时包含内部浮动元素。

使用clearfix清除浮动的元素本身并未产生BFC,依靠的是CSS的clear属性。即该元素若没有其他属性产生BFC时仍然按照普通文档流进行定位,垂直外边距还是存在折叠。

如何实现两列自适应布局?

不考虑使用UI框架中的布局组件情况下,直接使用float: left + 固定左侧宽度 + 右边列margin-left

<div><img style="float: left; width: 140px;" src="https://tva1.sinaimg.cn/large/00831rSTly1gcel7v9ji4j3041041wec.jpg" alt="logo"><div style="margin-left: 150px;"><p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quos eligendi numquam nihil excepturi sint reiciendis iusto maiores nostrum fugiat harum?</p><p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quam, perspiciatis magnam consectetur corrupti suscipit a ratione sunt commodi beatae ad!</p></div>
</div>

实现效果如下图:

过程分析

左侧部分使用float: left会产生一个BFC元素,这个BFC与右侧块级元素div一起进行普通流定位;由于是两个按照普通流定位这个两个元素之前不会产生覆盖,即使不固定左侧元素宽度和右侧块级元素给margin-left也可以实现效果(这里给宽度是为了控制左侧固定尺寸)。

内联元素中使用块级元素会产生什么效果?

内联元素中插入块级元素会在插入的块级元素前后各产生一个匿名块与插入的块按照普通流进行定位

内联元素中使用插入浮动元素会产生什么效果?

内联元素使用了display: inline-block会产生一个IFC,其内部的浮动会在内部进行浮动定位,然后整个IFC看成一个块级元素与外部进行文档流定位

<span style="display: inline-block; background-color: #6EBD91;">Lorem ipsum dolor sit amet.<span style="float: left; background-color: chocolate;">Lorem, ipsum.</span><div style="background-color: #F4D491;">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Repellat labore, ipsa quo possimus mollitia, officiis quia provident inventore placeat nulla, rem velit ratione ducimus. Facilis eos repudiandae debitis quam voluptatem.</div>Lorem ipsum dolor sit amet consectetur.
</span>

效果如下:

以上效果可以在线预览

参考文章

  • MDN-格式化上下文
  • MDN-clear
  • gihtub-介绍下BFC及其应用
  • 知乎专栏-10分钟理解BFC原理

写在最后

既然看到这里了不妨点个赞鼓励下作者呗 :)
作者博客:https://blog.lessing.online/
作者github:https://github.com/johniexu

bfc是什么_全面分析总结BFC原理及实践相关推荐

  1. bfc是什么_清除浮动和 BFC

    正常情况下,如果我们不给一个元素设置高度,那么这个元素的高度是由其子元素撑起来的. //html <div class="parent"><div class=& ...

  2. rl滤波器原理_图文分析滤波器工作原理以及电路设计技巧

    常见低通滤波电路 L  一阶滤波 C  一阶滤波 CL  二阶滤波 RC  二阶滤波 LC  二阶滤波 RCR  T型三阶滤波 LCL  T型三阶滤波 CRC π三阶滤波 CLC π三阶滤波 开关电源 ...

  3. 情感分析——深入snownlp原理和实践

    一.snownlp简介 snownlp是什么? SnowNLP是一个python写的类库,可以方便的处理中文文本内容,是受到了TextBlob的启发而写的,由于现在大部分的自然语言处理库基本都是针对英 ...

  4. 电路分析导论_生存分析导论

    电路分析导论 In our extremely competitive times, all businesses face the problem of customer churn/retenti ...

  5. 数据可视化分析票房数据报告_票房收入分析和可视化

    数据可视化分析票房数据报告 Welcome back to my 100 Days of Data Science Challenge Journey. On day 4 and 5, I work ...

  6. 面试官:什么是BFC?BFC有什么特性?如何创建BFC?BFC有什么作用?

    面试官:什么是BFC?BFC有什么特性?如何创建BFC?BFC有什么作用? 程序员鱼乐,全网同名,分享编程知识与生活日常.还是个小菜狗,喜欢分享知识,如有错误还请大佬们指出,欢迎大佬评论区补充知识. ...

  7. Python爬虫_案例分析(二)

    Python爬虫_案例分析(二) 一.电影天堂案例 import scrapy from scrapy_movie.items import ScrapyMovieItem class MvSpide ...

  8. 第09章_性能分析工具的使用

    第09章_性能分析工具的使用 文章目录 1. 数据库服务器的优化步骤 2. 查看系统性能参数 3. 统计SQL的查询成本:last_query_cost 4.定位执行慢的 SQL:慢查询日志 4.1 ...

  9. 实战微博互动预测之一_问题分析 以及 分布式下的事件驱动机制(Pub与Sub模式)

    实战微博互动预测之一_问题分析 2017年12月08日 13:21:04 xieyan0811 阅读数:2390 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csd ...

最新文章

  1. python视频下载-python动态视频下载器的实现方法
  2. android oom 全解析
  3. Codeforces Round #462 (Div. 2)题解
  4. winPcap_2_编译环境*注意*
  5. PostgreSQL 的 target_list分析(五)
  6. python解释器环境中用于表示上一次运算结果的特殊变量_判断正误 PUSH CL_学小易找答案...
  7. 模型压缩与加速:Octave Convolution
  8. js 获取中括号里面字符串_一日一技:一次性把字符串用多个分隔符分割
  9. 25. ThreadLocal的使用场景
  10. 如何 调系统相机_神仙理光相机,各种静物原片直出也太美了吧!!!
  11. JPDA 架构研究19 - JDI的连接模块
  12. Collection与Arrays
  13. 如何在调试Window App时,触发 Suspending ,Resuming 等事件
  14. 为知笔记登录提示“打开数据库失败”解决方法
  15. 彩色模型,及RGB,CMY,CMYK,HSI,CIE,YIQ,YUV相互转化及介绍
  16. # IE浏览器打不开网页,google浏览器能打开
  17. react 中子路由(route)或二级路由如何配置?
  18. GStreamer1.0 工具用法
  19. 计算机网络TCP拥塞控制窗口大小变化、重传、滑动窗口、流量控制等
  20. 大数据精准投放平台_大数据精准投放,让你摆脱千篇一律的广告投放!

热门文章

  1. java ee cdi_Java EE CDI程序化依赖关系消歧示例–注入点检查
  2. 惯用并发:flatMap()与parallel()– RxJava常见问题解答
  3. 将自定义功能添加到Spring数据存储库
  4. 仍然不安全:变成了Java 9功能的Java 6中的主要错误
  5. 在基于简单Vertx Rest的应用程序上为REST资源设置基本响应HTTP标头
  6. PrimeFaces 5.0 DataTable列切换器
  7. XAML或JavaFx?
  8. 在Eclipse中有效使用JUnit
  9. 使用直接内存时可以更快
  10. 解决Spring自动装配中的循环依赖