sggmico / fe-happy-interview

面试不迷茫
Apache License 2.0
5 stars 0 forks source link

【CSS专题】:BFC及其应用 #14

Open sggmico opened 3 years ago

sggmico commented 3 years ago

【CSS专题】: BFC及其应用

FC Formatting context(格式化上下文)是W3C 规范中的一个概念. 它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素如何定位,以及和其他元素的关系和相互作用.

BFC

BFC 即 Block Formatting Contexts (块级格式化上下文),它属于上述定位方案的普通流。

具有 BFC 特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器所没有的一些特性。

通俗一点来讲,可以把 BFC 理解为一个封闭的大箱子,箱子内部的元素无论如何翻江倒海,都不会影响到外部。

应用场景如下:

阻止:父元素高度塌陷

父元素包裹子元素(父元素高度自适应),当子元素设置浮动后,父元素会失去高度。此时需要给父元素触发BFC,实现父元素对子元素的包裹。

父元素高度塌陷效果图:

html代码:

<div class="father">
   <div class="son"></div>
</div>

css代码:

.father {
      width: 600px;
      background-color: thistle;
      border: 3px solid saddlebrown;

      /* 触发 BFC */
      /* overflow: hidden; */
      /* position: absolute; */
      /* display: inline-block; */
      /* display: table; */
      /* display: flex; */

      /* css3触发 BFC 专用, 没有副作用 */
      display: flow-root; 

    }

    .son {
      width: 400px;
      height: 200px;
      background-color: seagreen;
      float: left;
    }

上面示例,通过给父元素设置 display:flow-root 来触发BFC,实现了父元素对浮动子元素的包裹效果。

通过BFC阻止父元素高度塌陷之后的效果图:

防止:margin合并

​ 一般有两种情况会出现margin合并:

  1. 父子元素:子元素设置margin后,会穿透父级,作用于父元素的外边距。若父子元素都设置margin,取最大
  2. 相邻元素(上下):margin会合并,并以margin最大值显示

父子元素

父子元素margin合并效果图:

html代码:

<div class="father">
  <div class="son"></div>
</div>

css代码:

.father {
  width: 600px;
  height: 300px;
  background-color: thistle;

  /* 设置border也可以阻止父子元素margin合并 */
  /* border: 3px solid sandybrown; */

  /* 触发 BFC */
  /* overflow: hidden; */
  /* position: absolute; */
  /* display: inline-block; */
  /* display: table; */
  /* display: flex; */
  /* float: left; */

  /* css3触发 BFC 专用, 没有副作用 */
  /* display: flow-root; */

}

.son {
  width: 400px;
  height: 200px;
  background-color: seagreen;
  margin-top: 100px;
}

需要注意的是,除了通过给父元素设置触发BFC的方式,我们还可以给父元素设置border,来防止子元素的margin塌陷。

BFC阻止父子元素margin合并之后的效果图:

相邻元素:

相邻元素垂直方向上margin合并效果图:

html代码:

<!-- 需要将其中一个元素放入父级元素,并触发父级元素BFC,将子元素隔离 -->
<div class="father">
  <div class="item1"></div>
</div>
<!-- <div class="item1"></div> -->
<div class="item2"></div>

css代码:

.father {
  /* 触发 BFC */
  /* overflow: hidden; */
  /* position: absolute; */
  /* display: inline-block; */
  /* display: table; */
  /* display: flex; */
  /* float: left; */
  /* css3触发 BFC 专用, 没有副作用 */
  display: flow-root;
}

.item1 {
  width: 200px;
  height: 100px;
  background-color: thistle;
  margin-bottom: 50px;
}

.item2 {
  width: 200px;
  height: 100px;
  background-color: seagreen;
  margin-top: 100px;
}

BFC阻止相邻元素margin合并后的效果图:

BFC + 浮动元素: 多栏布局

html代码:

<div class="box">
   <div class="left"></div>
   <div class="right"></div>
   <!-- 中间区域位置 -->
   <div class="center"></div>
</div>

在实现三栏布局时,如上图,左、右、中三部分元素顺序,当设置左、右区域分别向左、向右浮动后。页面布局样式如图:

可见,左右部分覆盖在了绿色中间部分上,这种情况,我们可以给中间部分的容器触发BFC,即可实现三栏布局,样式规则设置如下。

css代码:

.left,
.right {
  width: 200px;
  height: 100px;
  background-color: sandybrown;
  float: left;
}

.right {
  float: right;
}

.center {
  height: 200px;
  background-color: seagreen;
  /* 触发 BFC,  */
  display: flow-root;
}

设置后的效果图:

小结

本文结合具体示例学习了BFC的应用场景:

  1. 阻止:父元素高度塌陷
  2. 阻止:margin合并
  3. BFC + 浮动元素:多栏布局

我们需要重点掌握的是,如果触发BFC,来解决具体的问题。触发BFC的条件如下(满足任意一点即可):

  1. body根元素
  2. 浮动元素:float:除none以为的值
  3. 绝对定位元素:position:absolute/fixed
  4. display:inline-block/table-cells/flex/flow-root(css3触发BFC专用,无副作用)
  5. overflow:除了visible以外的值(hidden/auto/scroll)

最后,如果觉得有用,顺便点个赞吧!你的支持是我最大的鼓励!

微信关注 “乘风破浪大前端”,发现更多有趣好文的前端知识和实战。

关于本文如有任何意见或建议,欢迎评论区讨论。