前端之BFC说明

一、定义

BFC - Block Formatting Context 块级格式化上下文 BFC的定义,在官方文档到中,是这么介绍BFC的。

重点:

1、每一个BFC区域只包括其子元素,不包括其子元素的子元素;

2、每一个BFC区域都是独立隔绝的,互不影响;

3、通过一些条件触发BFC,从而解决布局上出现的问题;

二、作用

BFC的触发条件

  1. 浮动元素 ( float 不取值为 none )

  2. 绝对定位元素 ( position 取值为 absolute 或 fixed )

  3. display 取值为 inline-block 、 table-cell 、 table-caption 、 flex 、 inline-flex 之一的元素

  4. overflow 不取值为 visible 的元素

  5. 根元素(body)

BFC的特性

  1. 属于同一个BFC的两个相邻容器的上下margin会重叠(重点)
  2. 计算BFC高度时浮动元素也参于计算(重点)
  3. BFC的区域不会与浮动容器发生重叠(重点)
  4. BFC内的容器在垂直方向依次排列
  5. 元素的margin-left与其包含块的border-left相接触
  6. BFC是独立容器,容器内部元素不会影响容器外部元素

三、代码演示 

问题一:外边距的塌陷问题(垂直塌陷),两个div盒子的margin重叠到一起。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style type="text/css">
    .box1{
        width: 200px;
        height: 200px;
        background: red;
        margin: 100px;
    }
    .box2{
        width: 200px;
        height: 200px;
        background: blue;
        margin: 100px;
    }
</style>
</head>
<body>
  <div class="box1"></div>
  <div class="box2"></div>
</body>
</html>

解决方案:BFC,创建与世隔绝的独立区域,不会互相影响,那么,我们可以将这两个盒子,放到两个BFC区域中,即可解决这个问题。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style type="text/css">
    .box1{
        width: 200px;
        height: 200px;
        background: red;
        margin: 100px;
    }
    .box2{
        width: 200px;
        height: 200px;
        background: blue;
        margin: 100px;
    }
     //增加两个单独的BFC区域
    .box_bfc{
      overflow: hidden;
    }
</style>
</head>
<body>
  <div class="box_bfc">
  <div class="box1"></div>
  </div>
  <div class="box_bfc">
  <div class="box2"></div>
  </div>
</body>
</html>

问题二:利用BFC解决包含塌陷

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style type="text/css">
    .box_bfc{
        width: 200px;
        height: 200px;
        background: red;
    }
    .box1{
        width: 100px;
        height: 100px;
        background: blue;
        margin-top: 20px;
    }
    
</style>
</head>
<body>
  <div class="box_bfc">
  <div class="box1"></div>
  </div>
</body>
</html>

解决方案:将父元素变成一个独立的BFC区域

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style type="text/css">
    .box_bfc{
        width: 200px;
        height: 200px;
        background: red;
        overflow: hidden;
        /* display: flex、inline-block 、 table-cell 、 table-caption 、 flex 、 inline-flex */
        /* position: absolute 或 fixed; */
    }
    .box1{
        width: 100px;
        height: 100px;
        background: blue;
        margin-top: 20px;
    }
    
</style>
</head>
<body>
  <div class="box_bfc">
  <div class="box1"></div>
  </div>
</body>
</html>

问题三:当子元素浮动是,父元素没有设定高度时,父元素会高度塌陷

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style type="text/css">
    .box_bfc{
        /* width: 200px; */
        /* height: 200px; */
        background: red;
        border: 10px solid rgb(30, 255, 0);
        /* overflow: hidden; */
        /* display: flex、inline-block 、 table-cell 、 table-caption 、 flex 、 inline-flex */
        /* position: absolute 或 fixed; */
    }
    .box1{
        width: 100px;
        height: 100px;
        background: blue;
        float: left;
    }
    
</style>
</head>
<body>
  <div class="box_bfc">
  <div class="box1"></div>
  </div>
</body>
</html>

解决方案:使得父元素触发BFC,计算BFC高度时浮动元素也参于计算,此时子元素虽然设置了浮动,但其高度仍计算至父元素内,从而解决了高度塌陷问题。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style type="text/css">
    .box_bfc{
        /* width: 200px; */
        /* height: 200px; */
        background: red;
        border: 10px solid rgb(30, 255, 0);
        overflow: hidden;
        /* display: flex、inline-block 、 table-cell 、 table-caption 、 flex 、 inline-flex */
        /* position: absolute 或 fixed; */
    }
    .box1{
        width: 100px;
        height: 100px;
        background: blue;
        float: left;
    }
    
</style>
</head>
<body>
  <div class="box_bfc">
  <div class="box1"></div>
  </div>
</body>
</html>

问题四:左侧元素浮动时,会与右侧元素发生重叠。左侧元素浮动,脱离文档流。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style type="text/css">
    .box1{
        width: 100px;
        height: 100px;
        background: blue;
        float: left;
    }
    .box2{
        width: 200px;
        height: 200px;
        background: red;
    }
    
</style>
</head>
<body>
  <div class="box1"></div>
  <div class="box2"></div>
</body>
</html>

解决方案:红色区域触法BFC,BFC的区域不会与浮动容器发生重叠

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style type="text/css">
    .box1{
        width: 100px;
        height: 100px;
        background: blue;
        float: left;
    }
    .box2{
        width: 200px;
        height: 200px;
        background: red;
        float: left;
        /* overflow: hidden; */
    }
    
</style>
</head>
<body>
  <div class="box1"></div>
  <div class="box2"></div>
</body>
</html>

BFC功能总结

1、可以利用BFC解决两个相邻元素的上下margin重叠问题;
2、可以利用BFC解决高度塌陷问题;
3、可以利用BFC实现多栏布局(两栏、三栏、圣杯、双飞翼等)。

布局 

1、两栏布局

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style type="text/css">
    * {
        margin: 0px;
        padding: 0px;
    }
    
    .left {
        width: 200px;
        height: 50px;
        background: aqua;
        float: left;
    }
    
    .right {
        height: 50px;
        overflow: hidden;
        background: aquamarine;
    }
</style>
</head>
<body>
  <div class="left">固定宽度</div>
    <div class="right">自适应宽度</div>

</body>
</html>

2、三栏布局

定义:圣杯布局双飞翼布局,两者的功能相同,都是为了实现一个两侧宽度固定,中间宽度自适应的三栏布局。

圣杯布局:渲染——中间在前,左侧在后
<div class="whole-page container">
  <div class="middle">中间</div>
  <div class="left">左侧</div>
  <div class="right">右侧</div>
</div>
<style>
.whole-page {
  height: 100vh;
  min-width:calc(var(--left-value) + var(--right-value) + 200px);
}
.container {
  --left-value: 400px;
  --right-value: 300px;
  padding: 0 var(--right-value) 0 var(--left-value);
  .left {
    float: left;
    position: relative;
    left: calc(-1 * var(--left-value));
    width: var(--left-value);
    background-color: pink;
    height: 100%;
//使用负magrin来实现。在设置了浮动且移动到父元素边框以外时,就会向上浮动。
    margin-left: -100%;
  }
  .right {
    float: left;
    width: var(--right-value);
    background-color: green;
    height: 100%;
    margin-right: calc(-1 * var(--right-value));
  }
  .middle {
    float: left;
    background-color: yellow;
    height: 100%;
    width: 100%;
  }
}
</style>
圣杯布局上下三栏嵌套
<div class="whole-page container">
  <div class="top">上面</div>
  <div class="middle">
    <div class="middle-deep">中间</div>
    <div class="left">左侧</div>
    <div class="right">右侧</div>
  </div>
  <div class="bottom">下面</div>
</div>
<style>
.whole-page {
  height: 100vh;
  min-width:calc(var(--left-value) + var(--right-value) + 200px);
}
.container {
  --top-value: 300px;
  --bottom-value: 200px;
  --left-value: 400px;
  --right-value: 300px;
  .top {
    height: var(--top-value);
    background-color: pink;
  }
  .bottom {
    height: var(--bottom-value);
    background-color: green;
  }
  .middle {
    height: calc(100% - var(--top-value) - var(--bottom-value));
    padding: 0 var(--right-value) 0 var(--left-value);
    .left {
      float: left;
      position: relative;
      left: calc(-1 * var(--left-value));
      width: var(--left-value);
      background-color: grey;
      height: 100%;
      margin-left: -100%;
    }
    .right {
      float: left;
      width: var(--right-value);
      background-color: aqua;
      height: 100%;
      margin-right: calc(-1 * var(--right-value));
    }
    .middle-deep {
      float: left;
      background-color: yellow;
      height: 100%;
      width: 100%;
    }
  }
}
</style>
双翼飞布局:解决了圣杯布局要求中间区域最小宽度的问题
<div class="whole-page container">
  <div class="middle">
    <div class="inner">中间</div>
  </div>
  <div class="left">左侧</div>
  <div class="right">右侧</div>
</div>
<style>
.whole-page {
  height: 100vh;
}
.container {
  --left-value: 400px;
  --right-value: 300px;
  .left {
    background-color: pink;
    height: 100%;
    width: var(--left-value);
    float: left;
    margin-left: -100%;
  }
  .right {
    background-color: green;
    height: 100%;
    width: var(--right-value);
    float: left;
    margin-left: calc(-1 * var(--right-value));
  }
  .middle {
    background-color: yellow;
    height: 100%;
    width: 100%;
    float: left;
    .inner {
      padding-left: var(--left-value);
      padding-right: var(--right-value);
      height: 100%;
    }
  }
}
</style>
双翼飞布局三层嵌套:
<div class="whole-page container">
  <div class="top">上面</div>
  <div class="middle">
    <div class="middle-deep">
      <div class="inner">中间</div>
    </div>
    <div class="left">左侧</div>
    <div class="right">右侧</div>
  </div>
  <div class="bottom">下面</div>
</div>
<style>
.whole-page {
  height: 100vh;
}
.container {
  --top-value: 300px;
  --bottom-value: 200px;
  --left-value: 400px;
  --right-value: 300px;
  .top {
    height: var(--top-value);
    background-color: pink;
  }
  .bottom {
    height: var(--bottom-value);
    background-color: green;
  }
  .middle {
    height: calc(100% - var(--top-value) - var(--bottom-value));
    .left {
      background-color: grey;
      height: 100%;
      width: var(--left-value);
      float: left;
      margin-left: -100%;
    }
    .right {
      background-color: aqua;
      height: 100%;
      width: var(--right-value);
      float: left;
      margin-left: calc(-1 * var(--right-value));
    }
    .middle-deep {
      background-color: yellow;
      float: left;
      height: 100%;
      width: 100%;
      .inner {
        margin-left: var(--left-value);
        margin-right: var(--right-value);
        height: 100%;
      }
    }
  }
}
</style>

3、更多布局(flex grid)

圣杯布局/双飞翼布局/flex/grid等,实现CSS三栏自适应布局的几种方法 - 知乎

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值