BFC笔记

1.文档流

文档流其实分为定位流、浮动流、普通流三种。而普通流其实就是指BFC中的FC。FC(Formatting Context),直译过来是格式化上下文,它是页面中的一块渲染区域,有一套渲染规则,决定了其子元素如何布局,以及和其他元素之间的关系和作用。常见的FC有BFC、IFC,还有GFC和FFC。

常规流(Normal flow)

  • 在常规流中,盒一个接着一个排列;

  • 在块级格式化上下文里面, 它们竖着排列;

  • 在行内格式化上下文里面, 它们横着排列;

  • 当position为static或relative,并且float为none时会触发常规流;

  • 对于静态定位(static positioning),position: static,盒的位置是常规流布局里的位置;

  • 对于相对定位(relative positioning),position: relative,盒偏移位置由top、bottom、left、right属性定义。即使有偏移,仍然保留原有的位置,其它常规流不能占用这个位置。

浮动(Floats)

  • 左浮动元素尽量靠左、靠上,右浮动同理

  • 这导致常规流环绕在它的周边,除非设置 clear 属性

  • 浮动元素不会影响块级元素的布局

  • 但浮动元素会影响行内元素的布局,让其围绕在自己周围,撑大父级元素,从而间接影响块级元素布局

  • 最高点不会超过当前行的最高点、它前面的浮动元素的最高点

  • 不超过它的包含块,除非元素本身已经比包含块更宽

  • 行内元素出现在左浮动元素的右边和右浮动元素的左边,左浮动元素的左边和右浮动元素的右边是不会摆放浮动元素的

绝对定位(Absolute positioning)

  • 绝对定位方案,盒从常规流中被移除,不影响常规流的布局;

  • 它的定位相对于它的包含块,相关CSS属性:top、bottom、left、right;

  • 如果元素的属性position为absolute或fixed,它是绝对定位元素;

  • 对于position: absolute,元素定位将相对于上级元素中最近的一个relative、fixed、absolute,如果没有则相对于body;

2.BFC

(1)概念

块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视化CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。

(2)创建BFC的方式

  • float的值不是none。

  • position的值不是static或者relative。

  • display的值是inline-block、table-cell、flex、table-caption或者inline-flex

  • overflow的值不是visible

(3)BFC的作用

  • 避免父元素高度塌陷,让浮动内容和周围的内容等高,清除浮动

    我们让<div>元素浮动,并给了它一个边框效果,<div>里的内容现在已经在浮动元素周围浮动起来了。由于浮动的元素比它旁边的元素高,所以<div>的边框穿出了浮动,浮动脱离了文档流,所以<div>的background和border仅仅包含了内容,不包含浮动。

     

     

    .box {
             
              border: 5px solid rebeccapurple;
    }
    .float {
              float: left;
              width: 200px;
              height: 150px;
             
              border: 1px solid black;
              padding: 10px;
    }
     <div class="box">
           <div class="float">我是一个浮动的盒子</div>
           <p>我是容器里的内容</p>
    </div>
    使用overflow: auto

    创建一个会包含这个浮动的BFC,通常的做法是设置父元素 overflow: auto 或者设置其他的非默认的 overflow: visible 的值

   
.box{ 
overflow: auto;
          border: 5px solid rebeccapurple;
      }
.float {
          float: left;
          width: 200px;
          height: 150px;
          border: 1px solid black;
          padding: 10px;
      }
<div class="box">
       <div class="float">我是一个浮动的盒子</div>
       <p>我是容器里的内容</p>
</div>

设置 overflow: auto 创建一个新的BFC来包含这个浮动。我们的 <div> 元素现在变成布局中的迷你布局。任何子元素都会被包含进去。

使用 overflow 来创建一个新的BFC,是因为 overflow 属性告诉浏览器你想要怎样处理溢出的内容。当你使用这个属性只是为了创建BFC的时候,你可能会发现一些不想要的问题,比如滚动条或者一些剪切的阴影,需要注意。另外,对于后续的开发,可能不是很清楚当时为什么使用overflow。所以你最好添加一些注释来解释为什么这样做。

使用display: flow-root

一个新的 display 属性的值,它可以创建无副作用的BFC。在父级块中使用 display: flow-root 可以创建新的BFC。

 

 .box {

            display: flow-root;
          border: 5px solid rebeccapurple;
      }  
.float {
          float: left;
          width: 200px;
          height: 150px;
          border: 1px solid black;
          padding: 10px;
      }
<div class="box">
       <div class="float">我是一个浮动的盒子</div>
       <p>我是容器里的内容</p>
</div>

给display: flow-root 属性后,<div>中的所有内容都会参与BFC,浮动的内容不会从底部溢出。

  • 避免外边距折叠

当块级元素(block)的上外边距(margin-top)和下外边距(margin-bottom)同时都有设定时只会只会保留最大边距,这种行为称为外边距重叠。

.blue,
.red-inner {
          height: 50px;
          margin: 10px 0;
      }
.blue {
          background: blue;
      }
.red-inner {
          background: green;
      }
<div class="blue">blue</div>
<div class="red-inner">red inner</div>

属于同一个BFC的两个相邻的Box会发生margin重叠,所以我们可以设置两个不同的BFC。也就是我们可以让red-outer把第二个div(red-inner)包起来。

.blue,
.red-inner {
          height: 50px;
          margin: 10px 0;
      }      
.blue {
          background: blue;
      }      
.red-inner {
          background: green;
      }        
.red-outer {
          overflow: hidden;
          background: red;
      }

<div class="blue"></div>

   <div class="red-outer">
        <div class="red-inner">red inner</div>
</div>
  • 自适应两栏布局

每个盒子的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。因此,虽然存在浮动的元素nav,但main的左边依然会与包含块的左边相接触。

.container {

            width: 300px;
          position: relative;
}
.nav {
          width: 100px;
          height: 150px;
          float: left;
         
}
.main {
          height: 200px;
 
}
<div class="container">
       <div class="nav">nav</div>
       <div class="main">main</div>
</div>

由于BFC的区域不会与float box重叠。我们可以通过触发main生成 一个新的BFC, 来实现自适应两栏布局。当触发main生成BFC后,这个新的BFC不会与浮动的nav重叠。因此会根据包含块的宽度和nav的宽度,自动变窄。

 

 .container {

            width: 300px;
          position: relative;
}
.nav {
          width: 100px;
          height: 150px;
          float: left;
 
}
.main {
          overflow: hidden;
          height: 200px;
          background: lightblue;
}
<div class="container">
       <div class="nav">nav</div>
       <div class="main">main</div>
</div>
posted @ 2020-05-12 09:47  icyyyy  阅读(169)  评论(0)    收藏  举报