Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

初探 BFC #79

Open
yanyue404 opened this issue Oct 7, 2019 · 0 comments
Open

初探 BFC #79

yanyue404 opened this issue Oct 7, 2019 · 0 comments
Labels

Comments

@yanyue404
Copy link
Owner

何为 BFC?

块格式化上下文(Block Formatting Context,BFC) 是 Web 页面的可视化 CSS 渲染的一部分,它是页面中的一块渲染区域,有一套渲染规则,决定了其子元素如何布局,以及和其他元素之间的关系和作用。

BFC 对浮动定位与清除浮动都很重要。浮动定位和清除浮动时只会应用于同一个 BFC 内的元素。浮动不会影响其它 BFC 中元素的布局,而清除浮动只能清除同一 BFC 中在它前面的元素的浮动。外边距折叠(Margin collapsing)也只会发生在属于同一 BFC 的块级元素之间。

常见使用场景

清除浮动(让浮动内容与周围内容等高)

demo 演示:

* {
  margin: 0;
  padding: 0;
}
.demo {
  border: 1px solid pink;
}
.demo p {
  float: left;
  width: 100px;
  height: 100px;
  background: blue;
}
<div class="demo">
  <p></p>
</div>

下图可见#demo容器中的子元素浮动后脱离文档流,盒子容器高度为 2px

Snipaste_2019-10-07_18-21-39.png

解决方法:
触发父容器的 BFC 属性,使里面的子元素都处在父的同一个 BFC 区域之内,此时已成功清除浮动。

#demo {
  border: 1px solid pink;
  overflow: hidden;
}

Snipaste_2019-10-07_18-31-14.png

外边距塌陷

demo 演示:

.blue,
.red-inner {
  height: 50px;
  margin: 10px 0;
}

.blue {
  background: blue;
}

.red-inner {
  background: red;
}
<div class="blue"></div>
<div class="red-outer ">
  <div class="red-inner">red inner</div>
</div>

由下图可知,两个盒子的外边距重叠,为10px

Snipaste_2019-10-07_18-49-55.png

解决办法:将 .red-outer盒子设置为 BFC 盒子,隔离两个颜色的盒子

.red-outer {
  overflow: hidden;
}

可以阻止元素被浮动元素覆盖

demo 演示:

* {
  margin: 0;
  padding: 0;
}
.demo1 {
  width: 100px;
  height: 100px;
  float: left;
  background: pink;
}
.demo2 {
  width: 200px;
  height: 200px;
  background: blue;
}
<div class="demo">
  <div class="demo1">我是一个左侧浮动元素</div>
  <div class="demo2">我是一个没有设置浮动, 也没有触发BFC的元素</div>
</div>

如下图:demo2 部分区域被浮动元素 demo1 覆盖, 但是文字没有覆盖, 即文字环绕效果。

Snipaste_2019-10-07_19-12-08.png

解决办法: 修改背景为蓝色的盒子的属性值,使其成为 BFC,以此阻止被粉色的浮动盒子覆盖。

.demo2 {
  /* 添加触发 BFC 条件 */
  overflow: hidden;
}

Snipaste_2019-10-07_19-20-01.png

自适应两栏布局

* {
  margin: 0;
  padding: 0;
}
.container {
  height: 300px;
}
.float {
  width: 200px;
  height: 100%;
  float: left;
  background: red;
  margin-right: 10px;
}

.main {
  background: green;
  height: 100%;
  overflow: hidden;
}
<div class="container">
  <div class="float">
    浮动元素
  </div>
  <div class="main">
    自适应
  </div>
</div>

如下图所示:

Snipaste_2019-10-07_19-32-21.png

这种主要是应用到 BFC 的一个特性:

1.浮动元素的块状兄弟元素会无视浮动元素的位置,尽量占满一行,这样该兄弟元素就会被浮动元素覆盖

2.若浮动元素的块状兄弟元素为 BFC,这不会占满一行,而是根据浮动元素的宽度,占据该行剩下的宽度,避免与浮动元素重叠

3.浮动元素与其块状 BfC 兄弟元素之间的 margin 可以生效,这会继续减少兄弟元素的宽度

触发 BFC 的条件

  • 根元素()
  • 浮动元素(元素的 float 不是 none)
  • 绝对定位元素(元素的 position 为 absolute 或 fixed)
  • 行内块元素(元素的 display 为 inline-block)
  • 表格单元格(元素的 display 为 table-cell,HTML 表格单元格默认为该值)
  • 表格标题(元素的 display 为 table-caption,HTML 表格标题默认为该值)
  • 匿名表格单元格元素(元素的 display 为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是 HTML table、row、tbody、thead、tfoot 的默认属性)或 inline-table)
  • overflow 值不为 visible 的块元素
  • display 值为 flow-root 的元素
  • contain 值为 layout、content 或 paint 的元素
  • 弹性元素(display 为 flex 或 inline-flex 元素的直接子元素)
  • 网格元素(display 为 grid 或 inline-grid 元素的直接子元素)
  • 多列容器(元素的 column-count 或 column-width 不为 auto,包括 column-count 为 1)
  • column-span 为 all 的元素始终会创建一个新的 BFC,即使该元素没有包裹在一个多列容器中

参考文章

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant