BFC理解与应用

理解BFC

理解BFC(块级格式化上下文)之前,先看一下FC(格式化上下文)是什么意思:

格式化上下文是决定盒子之间如何布局的环境,不同的格式化上下文如何布局盒子由自身的规则来决定。正常文档流下,盒模型归属到格式化上下文。块级盒子参加块级格式化上下文

BFC块格式化上下文 是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。因此BFC是一块独立渲染区域,内部元素的渲染不会影响边界以外的元素

BFC规则

内部盒子会在垂直方向排列

在同一个BFC中,垂直方向上,相邻两个盒子的margin会重叠,值取两者中较大的

BFC就是页面上的一个隔离的独立容器,里外互相不受影响

计算BFC元素的高度时,考虑BFC所包含的所有子元素,连浮动元素也要参与计算。

当元素不是BFC的子元素时,浮动元素高度不参与BFC计算(常见的盒子塌陷问题)

在一个BFC中,每个元素的左边缘都会紧贴着包含块的左边缘

BFC的区域不会与float box重叠。

BFC触发条件

  • 根元素html
  • 浮动元素(float不为none的元素)
  • 绝对定位元素(position为absolute或fixed)
  • overflow不为visible或clip的块级元素
  • 行内块元素(display为inline-block), 表格单元格(display为table-cell)
  • display值为table-caption, flex, inline-flex
  • display 值为 flow-root 的元素

使用 overflow: auto; 触发 BFC 的方法缺点在于不够直观,其次可能产生不必要的滚动条或剪切阴影等副作用。

因此mdn指出,使用 display: flow-root (或 display: flow-root list-item)将创建一个新的 BFC,而不会产生任何其他潜在的问题副作用。flow-root 关键字的意义是,创建的内容本质上类似于一个新的根元素(如 所做),并确定这个新的上下文如何创建及其流布局如何实现。

所以总结一句话,为一个元素创建BFC,可以包含内部浮动。排除外部浮动,阻止外边距重叠

BFC应用1: 解决margin重叠

xml 复制代码
<head>
  <meta charset="UTF-8">
  <style>
    .box1 {
      width: 100px;
      height: 100px;
      background-color: green;
      margin-bottom: 30px;
    }
    .box2 {
      width: 200px;
      height: 100px;
      background-color: green;
      margin-top: 50px;
    }

  </style>
</head>
<body>
  <div class="box1">盒子1</div>
  <div class="box2">盒子2</div>
</body>

如下图所示,box1和box1此时同处于html的BFC中,并且box1和box2在垂直方向上相邻,所以会出现margin重叠,取两者其中较大的值50px

那么如何解决呢?错误做法是直接给box1添加一个BFC,此时box1确实是已经形成了BFC(可以理解成box1内部形成了BFC),但是对于box1这个元素的本身,还是和box2同属于html的BFC中,所以还是会发生margin重叠

正确做法:要给box1套一层,然后给box1外层的盒子设置BFC

xml 复制代码
<head>
  <meta charset="UTF-8">
  <style>
    .box1 {
      width: 100px;
      height: 100px;
      background-color: green;
      margin-bottom: 30px;
    }
    .box2 {
      width: 200px;
      height: 100px;
      background-color: green;
      margin-top: 50px;
    }
    .container {
      overflow: hidden;
    }

  </style>
</head>
<body>
  <div class="container">
    <div class="box1">盒子1</div>
  </div>
  <div class="box2">盒子2</div>
</body>

此时成功解决上下margin塌陷问题

BFC应用2:解决浮动高度塌陷问题

考虑如下场景

当给container里面的box设置浮动的时候,该div元素会脱离文档流,此时container不会有高度。

xml 复制代码
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .container {
      background-color: yellowgreen;
      border: 2px solid black;
    }
    .box {
      border: 1px solid black;
      width: 100px;
      height: 100px;
      float: left;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="box">盒子1</div>
  </div>
</body>

当元素不是BFC的子元素时,浮动元素高度不参与BFC计算(常见的盒子塌陷问题)

BFC能解决浮动元素塌陷问题的原因在于:计算BFC元素的高度时,考虑BFC所包含的所有子元素,连浮动元素也要参与计算。所以为container元素添加overflow属性来设置BFC,此时container是一个新的BFC,计算高度时会包含浮动的子元素,因此解决浮动塌陷问题。

xml 复制代码
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .container {
      background-color: yellowgreen;
      border: 2px solid black;
      overflow: hidden;
    }
    .box {
      border: 1px solid black;
      width: 100px;
      height: 100px;
      float: left;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="box">盒子1</div>
  </div>
</body>

BFC应用3:自适应两栏布局

每个元素的左外边距与包含块的左边界相接触。即使元素浮动,也会同样。

xml 复制代码
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    .left {
      width: 100px;
      height: 150px;
      float: left;
      background: gray;
    }

    .right {
      height: 300px;
      background: rgb(170, 54, 236);
      background: yellowgreen;
    }
  </style>
</head>
<body>
  <div class="left">LEFT</div>
  <div class="right">RIGHT</div>
</body>

创建一个新的BFC会排除外部浮动,因此为right创建BFC可以实现自适应两栏布局。为right元素添加overflow:hidden来创建一个新的BFC

css 复制代码
.right {
  height: 300px;
  background: rgb(170, 54, 236);
  background: yellowgreen;
  overflow: hidden;
}

参考:

juejin.cn/post/711708...

fe.okki.com/post/622d99...

相关推荐
y先森2 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy2 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
IT女孩儿3 小时前
CSS查缺补漏(补充上一条)
前端·css
想自律的露西西★6 小时前
用el-scrollbar实现滚动条,拖动滚动条可以滚动,但是通过鼠标滑轮却无效
前端·javascript·css·vue.js·elementui·前端框架·html5
彪8256 小时前
第十章 JavaScript的应用 习题
javascript·css·ecmascript·html5
旧林8437 小时前
第八章 利用CSS制作导航菜单
前端·css
asleep7019 小时前
第8章利用CSS制作导航菜单
前端·css
风尚云网14 小时前
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
前端·css·学习·html·html5·风尚云网
酷酷的威朗普17 小时前
医院绩效考核系统
javascript·css·vue.js·typescript·node.js·echarts·html5
渊兮兮17 小时前
Vue3 + TypeScript +动画,实现动态登陆页面
前端·javascript·css·typescript·动画