谈谈BFC和高度塌陷的问题

18 篇文章 0 订阅

当面试官问道你高度塌陷时,人们第一想到的方法一定是

1

2

3

4

5

6

7

.clearfix::after {

    content: '';

    display: block;

    clear: both;

    visibility: hidden;

    height: 0;

}

 对,没错,这是一个完美的解决方案,但是我们有考虑过这个方案的实现原理吗,或者面试管继续问你这个方法的原理是什么?是不是一脸懵,不懵的也别杠,接下来我通过排他法来展示他的原理

 1. 首先 ::after 是元素的伪元素,在元素后面生成伪元素

 2.content 是伪元素的内容,为空,只是让伪元素不显示,显然不是原理

 3. height:0 是为了让伪元素高度为0 ,显然不是

 4. visibility:hidden 是为了伪元素浏览器渲染但不显示,显然也不是

 5. display: block 只是为了让伪元素成为块级元素,成为触发 clear:both 的条件,有点关系

 6. clear:both 规定在左右两侧不允许出现浮动元素, 这便是清除浮动的原理了

 

那么为什么要清除浮动,最常见的原因是 外层容器高度塌陷,下面简单演示一下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

<style>

  .wrap {

    width: 200px;

    border: 1px solid #333;

  }

  .wrap:after {

    content: '伪元素';

  }

  .left {

    float: left;

    background: blue;

    height: 100px;

    width: 100px;

  }

  .right {

    float: left;

    background: red;

    height: 50px;

    width: 100px;

  }

</style>

<body>

  <div class="wrap">

    <div class="left"></div>

    <div class="right"></div>

  </div>

  <div style="background: #000; width: 200px;">ccc</div>

</body>

  

 

 

 这便是高度塌陷的情况,按理解来说,黑色的div 应该存在于 .weap 下面,这就轮到 clear:both 出场了

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

<style>

  .wrap {

    width: 200px;

    border: 1px solid #333;

  }

  .wrap:after {

    content: '';

    display: block;

    clear: both;

  }

  .left {

    float: left;

    background: blue;

    height: 100px;

    width: 100px;

  }

  .right {

    float: left;

    background: red;

    height: 50px;

    width: 100px;

  }

</style>

<body>

  <div class="wrap">

    <div class="left"></div>

    <div class="right"></div>

  </div>

  <div style="background: #000; width: 200px;">ccc</div>

</body>

  

 

 

 现在高度塌陷问题就解决了

 

接下来咱们聊聊 BFC, 触发BFC 也能解决高度塌陷等问题,咱们先来了解 BFC的概念及其规则

 1. 概念

  BFC的全称是 Block Formatting Contexts。

   Formatting Contexts是页面中的一块渲染区域,它拥有一套渲染规则,决定其子元素将如何定位,以及和其它元素的关系      和相互作用。说白了就是一个决定如何渲染元素的容器。

 2. BFC 的渲染规则

  ①: 内部的块级元素会在垂直方向,一个接一个地放置

  ②: 块级元素垂直方向的距离由margin 决定。属于同一个BFC的相邻元素的margin 会重叠

   3:  对于从左往右的格式化,每个元素(块级元素与行内元素)的左边缘,与包含块的左边缘相接触,(对于从右往左的格式化则相反)。即使包含块中的元素存在浮动也是如此,除非其中元素再生成一个BFC 

  ④: BFC的区域不会与浮动元素重叠。

  五:BFC是一个隔离的独立容器,容器里面的子元素和外面的元素互不影响

  ⑥: 计算BFC容器的高度时,浮动元素也参与计算。

 3. 触发 BFC 条件

1

2

3

4

5

根元素

float的值不是none。

position的值不是static或者relative。

display的值是inline-block、inline-flex、flex、flow-root、table-caption、table-cell。

overflow的值不是visible。

 4. BCF 应用

    4.1 规则二

       以上渲染规则,第一点很好理解,第二点我们用一盒例子来解释

1

2

3

4

<body>

    <div style="width:100px;height:100px;background:red;margin:20px;"></div>

    <div style="width:100px;height:100px;background:blue;margin:20px;"></div>

</body>

  

按样式代码来看,红块和蓝块之间间距应该是40px。但实际上是20px。这就是BFC渲染规则的第二点。

因为BFC的触发条件之一就是根元素,所以body就是一个BFC容器,红块和蓝块是同在body下的相邻块级元素,其margin会生重叠,所以红块和蓝块之间间距只有20px

我们利用BFC渲染规则第2点(属于同一个BFC的两个相邻块级元素的margin会发生重叠),那么不属于同一个BFC的两个相邻块级元素的margin就不会发生重叠。

那么我们在第二个div元素用一个div元素包裹起来,并用overflow:auto触发其BFC。再看一下效果是不是不重叠了。

1

2

3

4

5

6

<body>

    <div style="width:100px;height:100px;background:red;margin:20px;"></div>

    <div style="overflow:auto">

        <div style="width:100px;height:100px;background:blue;margin:20px;"></div>

    </div>

</body>

 

     4.2 实现自适应两栏布局

自适应两栏布局,是一个主内容区域和一个侧边栏区域组成,两个区域的宽度都可以随窗口大小自适应。有很多种写法可以实现,我们这里使用BFC 实现 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<style>

    .main{

        background: red;

        height:500px;

    }

    .sider {

        float: left;

        width: 20%;

        height:300px;

        background: blue;

    }

</stley>

<body>

    <div class="sider">我是侧边栏</div>

    <div class="main">我是主体内容</div>

<body>

  

 

 

首先我们根据规则1,要先把.sider div写在.main div前面。这个.sider div才会浮动起来覆盖在.main div上面。

再根据规则4(BFC的区域不会与浮动元素重叠),给.main加上overflow:auto;触发.main div生成BFC。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值