BFC的基础理解及应用场景

  最近学习了BFC,开始学习的时候,单纯看概念,有种云里雾里的感觉,字都认识,凑一起啥意思大致也知道,但是具体有什么用呢?

这个就有点迷迷糊糊的,经过老师的讲解,以及自己课后的代码实验与总结,就拨云见日了,在这里分享自己对BFC的一些理解。

BFC的概念:

  BFC 即(Block Formatting Context)块级格式化上下文,指一个独立的块级渲染区域,只有块级盒子(box)参与,该区域拥有一套渲染规则来约束块级盒子的布局,且与区域外部无关。

    与之对应的还有IFC、GFC、FFC。

BFC的形成:

  1、根元素  html标签就是一个bfc

  2、float的值不为none

  3、overflow的值不为visible

  4、display的值为 inline-block/ table-cell/ table-caption/ flex/ inline-flex

  5、position的值为absolute或fixed

BFC的特性:

  1、Box垂直方向的距离由margin决定,属于同一个BFC的两个相邻box的margin会发生重叠

  2、计算BFC的高度时,浮动元素也参与计算

  3、BFC的区域不会与float box发生重叠

  4、BFC内部的Box会在垂直方向,一个接一个的放置。

  5、每个元素的margin box的左边会与包含块border box的左边相接触(对于从左到右的格式化,否则相反),即使存在浮动也会如此。

  6、BFC就是页面上的一个独立容器,容器里面的元素不会影响到外面的元素

  看到这里,肯定有些伙伴知道BFC以及开始慢慢知道BFC是个什么东西了,如果把html和css看做是数学,那么BFC就是一个公式,用来解决页面布局中的一些问题。

BFC在页面布局中的应用及原理

  运用BFC的特性,可以用来解决在页面布局中常见bug,也可以用来实现两栏、三栏布局、还可以解释我们页面布局中块状元素布局的规则

  1、解决页面布局中常见的bug

    • 两个垂直放置的box,上面的box设置margin-bottom,下面的box设置margin-top会发生重叠,最后浏览器解析的两个box之间的距离是两个box之间margin值大的那个数值。    

     常用的解决方法之一就是过下面的box添加父元素,并过父元素添加overflow:hidden;

     原理:首先,html是一个BFC,根据其特性,同一个BFC的两个相邻box的margin会发生重叠,所以导致这个问题。而添加overflow的解决方法,就是这针对这条特性,既然它要求在同一个BFC内会触发这个特性,那么让它

        不在同一个BFC区域内就行,也就是:给下面添加父元素,然后通过添加声明overflow:hidden;将父元素包含的区域变成了BFC区域,而下面的box和上面的box不在同一个BFC区域,自然也就不会再触发重叠的特性了。

        同样,你可以用其他的方法将这两个box不放在同一个BFC区域,也能解决这个问题,但是可能会造成其他问题,所以需要注意。

     是不是感觉有点意思呢,了解了问题产生的原因,再去解决问题就轻松许多了

                                        没有给下面的boX添加父元素和声明                     

                   

              给下面的box添加父元素和给父元素声明overflow:hidden;

           

      

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=di, initial-scale=1.0">
 6     <title>Document</title>
 7     <style>
 8         body{
 9             margin: 0;
10             padding: 0;
11         }
12         .box1{
13             width: 200px;
14             height: 200px;
15             background-color: red;
16             margin-bottom: 100px;
17         }
18         .box2{
19             width: 300px;
20             height: 300px;
21             background-color: blue;
22             margin-top: 150px;
23         }
24         .box3{
25             overflow: hidden;
26         }
27     </style>
28 </head>
29 <body>
30     <div class="box1">上面的盒子</div>
31     <div class="box3">
32         <div class="box2">下面的盒子</div>
33     </div>
34 </body>
35 </html>

    • 父元素没有设置高度,子元素全部浮动,会出现高度塌陷

      根据BFC的特性:计算BFC的高度时,浮动元素也参与计算。所以,解决方法也就显而易见了,将其父元素添加声明变成BFC即可。这也我们常用的解决方法,给父元素添加overflow:hidden;

            父元素没有高度,子元素浮动,可看到父元素高度只有边框撑起了的20px             

         

            给父元素添加overflow:hidden之后,浮动元素就参与了父元素高度的计算

         

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <title>Document</title>
 7     <style>
 8         body{
 9             margin: 0;
10             padding: 0;
11         }
12         .box{
13             overflow: hidden;
14             border: 10px solid blue;
15         }
16         .box1{
17             width: 100px;
18             height: 100px;
19             background-color: red;
20             float: left;
21         }
22         .box2{
23             width: 200px;
24             height: 200px;
25             background-color: pink;
26             float: left;
27         }
28         .box3{
29             width: 300px;
30             height: 300px;
31             background-color: yellow;
32             float: left;
33         }
34     </style>
35 </head>
36 <body>
37     <div class="box">
38         <div class="box1"></div>
39         <div class="box2"></div>
40         <div class="box3"></div>
41     </div>
42 </body>
43 </html>

        

   注:此方法不是最好的解决高度塌陷的方法,想了解更多可以参考:https://www.cnblogs.com/caption-yi-yang/p/12349729.html

 2、实现自适应的两栏、三栏布局

    根据BFC特性中:BFC的区域不会与float box发生重叠。这一特性,可以实现页面的一侧box宽度固定,另外一侧box自适应的两栏布局,也可以实现两侧box宽度固定,中间box宽度自适应的三栏布局

    • 两栏布局

      让上面的元素浮动,下面的一个元素没有浮动,那么下面的元素会上去,也可以实现两栏布局,但是下面的元素会跟上面发生重叠,这样就影响页面的布局。

      当给下面的元素添加了float/overflow/display的时候就不重叠了,因为给了这些声明之后,就触发下面的元素为BFC,而BFC里面规定BFC区域不会与浮动盒子发生重叠。

      如果既要BFC区域不会与float box发生重叠,又要右边的容器自适应可以给下面的元素添加声明overflow:hidden/auto/scroll或display:flex。

               上面盒子浮动,下面盒子不触发BFC                   

                

              上面盒子浮动,下面盒子触发BFC

         

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <title>Document</title>
 7     <style>
 8         body{
 9             margin: 0;
10             padding: 0;
11         }
12         /* .left{width: 300px;height: 300px; background: red;float: left;}
13         .right{height: 600px; background: yellow;} */
14         /* .left{width: 300px;height: 300px; background: red;float: left;}
15         .right{width: 400px;height: 600px; background: yellow;display: flex;} */
16         .left{width: 300px;height: 300px; background: red;float: left;}
17         .right{height: 600px; background: yellow;overflow: hidden;}
18     </style>
19 </head>
20 <body>
21
22         <div class="left">
23         </div>
24         <div class="right">
25         </div>
26 </body>
27 </html>

    • 三栏布局

      三栏布局的原理同两栏布局一样,中间元素触发BFC保证不与左右两侧元素重叠,左右两侧可以用浮动或者定位保持在中间元素的左右两侧

                      

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <title>Document</title>
 7     <style>
 8         body{
 9             margin: 0;
10             padding: 0;
11         }
12         .left{width: 100px;height: 200px;background: red;float: left;}
13         .center{height: 400px;background: yellow;overflow: hidden;margin-right: 200px;}
14         .right{width: 200px;height: 300px;background: deeppink;position: absolute;right: 0;top: 0;}
15     </style>
16 </head>
17 <body>
18     <div class="left"></div>
19     <div class="center"></div>
20     <div class="right"></div>
21 </body>
22 </html>

      注:三栏布局的方法很多,如想了解三栏布局中经典的圣杯布局和双飞翼布局可以参考:

3、解释页面布局中块状元素布局的规则

    • BFC内部的Box会在垂直方向,一个接一个的放置。

                          可以看到BFC区域内部的块元素是独占一行

                  

    • 每个元素的margin box的左边会与包含块border box的左边相接触(对于从左到右的格式化,否则相反),即使存在浮动也会如此。

                     图片中黄色部分是红色盒子边框,可以看到于里面盒子的左外边距相接触

                      

4、总结

 对于BFC,我们知道只需要熟记生成BFC区域的方法和上述特性中的1、2、3种(其余三种了解即可),然后根据其特性,在合适的地方生成BFC区域去解决一些问题,

 或者达到相要的布局效果即可

  希望能对伙伴们起到作用,同时如果有伙伴发现不足之处,请伙伴们指点!

 最后,用一句诗与伙伴们共勉-----不经一番寒彻骨,怎得梅花扑鼻香!

原文地址:https://www.cnblogs.com/mz33/p/12353370.html

时间: 2024-11-09 03:35:26

BFC的基础理解及应用场景的相关文章

伪元素、伪类基础理解

前几天同事问我css中单冒号和双冒号是什么意思,我也模糊得很,只有个笼统的概念就是:伪元素和伪类.一直以为,页面布局中很少使用到伪类,结果细细研究发现我们经常使用的hover就是一个最简单的伪类,顿时觉得自己太OUT了,紧跟着这两天都在看这些东西,其实伪类最简单的理解就是用于向某些选择器添加特殊的效果. 具体伪类.伪元素有哪些我就不一一列举,在w3c中列举的很清楚.我主要写写应用的实例. 1.来个简单的,咱们最常用到的向超链接添加不同的颜色: <html> <head> <m

jvm基础理解

一.jvm运行时内存区域 包含堆,虚拟机栈,本地栈(调用native方法时用到),方法区(perm区),程序计数器. 假设32位操作系统,这时系统限制每个进程大小为2G.这样上述这些区域(对于本地栈及程序计数器来讲,是无法设置的,hotspot有提供-Xoss参数用于设置本地方法栈.但实际是无效的)可以用相应参数设置,共同划分全部2G内存. 注意还有一块直接内存,不属于JAVA运行时区域.但是它的空间用得太多的话,还是受限于物理内存和虚拟内存总大小,因此也会抛出OutOfMemory.典型的re

C#委托零基础理解

C#委托零基础理解(转) 1,  为什么使用委托  2.什么是委托  3.委托如何使用 为什么使用委托? 委托是c#中非常重要的一个概念,使用委托使程序员可以将方法引用封装在委托对象内.然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调用哪个方法.与C或C++中的函数指针不同,委托是面向对象,而且是类型安全的. 什么是委托? 委托是一种引用方法的类型,一旦为委托分配了方法,委托将与该方法具有相同的行为,委托方法的使用和其他方法一样,具有参数和返回值. 如何使用委托 下面咱们

零基础理解Binder

写在前面的 当一个Android App存在某个不需要UI的后台运行需求时,或者是因为内存占用需要采用多进程方案时,我们免不了与多进程打交道.必不可少的,需要考虑Binder在其中如何实现. 最常见的Binder实现当然是AIDL,然而Binder的实现绝不仅仅只有AIDL一种方式,如果止步于写.aidl,那么对于Binder,对于Android整体的跨进程传输过程的理解都只能流于形式. 但是想理解Binder不是一件容易的事情,Binder的概念涉及太多知识点,遍观各大论坛上关于Binder的

Deep Learning基础--理解LSTM/RNN中的Attention机制

导读 目前采用编码器-解码器 (Encode-Decode) 结构的模型非常热门,是因为它在许多领域较其他的传统模型方法都取得了更好的结果.这种结构的模型通常将输入序列编码成一个固定长度的向量表示,对于长度较短的输入序列而言,该模型能够学习出对应合理的向量表示.然而,这种模型存在的问题在于:当输入序列非常长时,模型难以学到合理的向量表示. 在这篇博文中,我们将探索加入LSTM/RNN模型中的attention机制是如何克服传统编码器-解码器结构存在的问题的. 通过阅读这篇博文,你将会学习到: 传

Deep Learning基础--理解LSTM网络

循环神经网络(RNN) 人们的每次思考并不都是从零开始的.比如说你在阅读这篇文章时,你基于对前面的文字的理解来理解你目前阅读到的文字,而不是每读到一个文字时,都抛弃掉前面的思考,从头开始.你的记忆是有持久性的. 传统的神经网络并不能如此,这似乎是一个主要的缺点.例如,假设你在看一场电影,你想对电影里的每一个场景进行分类.传统的神经网络不能够基于前面的已分类场景来推断接下来的场景分类. 循环神经网络(Recurrent Neural Networks)解决了这个问题.这种神经网络带有环,可以将信息

javascript之闭包理解以及应用场景

之前读了js权威指南,也写了篇博文,但是实话实说当初看闭包确实还是一头雾水.现在时隔一个多月(当然这一段时间还是一直有在看闭包的相关知识)理解就更深入了一点,下面说说我的理解. 1 function fn(){ 2 var a = 0; 3 return function (){ 4 return ++a; 5 } 6 } 如上所示,上面第一个return返回的就是一个闭包,那么本质上说闭包就是一个函数.那么返回这个函数有什么用呢? 那是因为这个函数可以调用到它外部的a这个变量.其实也就是说,r

初涉网络,自己对服务器的一些基础理解

首先感谢bangumi.tv技术宅真可怕小组的各位提供的指点与帮助 万能的bangumi,请务必不要嫌弃我的无知 因为自己对网络了解较少,所以可能自己的理解有偏差或者因为便于自己理解而不严谨,所以请看到的各位理解(会有人看到吗),希望也不太懂的各位谨慎相信,希望很懂的各位指点. 以下是自己的理解与疑问,摘自bangumi连接. 最近自己学习建立网站,接触了很多云/vps/虚拟主机/服务器 等等很多东西,因为以前对网络方面基本没有了解,所以乱的现在快要爆炸了. 按照我以前的理解,所谓服务器或者云,

2017-2-17,c#基础,输入输出,定义变量,变量赋值,int.Parse的基础理解,在本的初学者也能看懂(未完待续)

计算机是死板的固定的,人是活跃的开放的,初学c#第一天给我的感觉就是:用人活跃开放式的思维去与呆萌的计算机沟通,摸清脾气,有利于双方深入合作,这也是今晚的教训,细心,仔细,大胆 c#基础 1.Hello!World!!! 1 { //输出Hello!World!!; 2 Console.WriteLine("Hello!World!!!"); 3 //防止闪退; 4 Console.ReadLine(); 5 6 } 踏入IT世界的第一步,向世界问好 2.string定义变量 套用向老