BFC以及BFC如何解决margin折叠和float导致高度塌陷

BFC

Boxes in the normal flow belong to a formatting context, which may be block or inline, but not both simultaneously. Block-level boxes participate in a block formatting context. Inline-level boxes participate in an inline formatting context.

上面的意思是:盒子在标准流中属于FC,是块级或者行内两者之一。块级元素布局所在的环境则属于BFC,行内元素布局所在的环境则属于IFC。

BFC:块级元素所在的布局环境就是BFC。

形成BFC的条件

  • 根元素(< html >)
  • 浮动元素(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、tr、tbody、thead、tfoot 的默认值)或 inline-table)
  • overflow 值不为 visible、clip 的块元素
  • display 值为 flow-root 的元素
  • contain 值为 layout、content 或 paint 的元素
  • 弹性元素(display 值为 flex 或 inline-flex 元素的直接子元素),如果它们本身既不是 flex、grid 也不是 table 容器
  • 网格元素(display 值为 grid 或 inline-grid 元素的直接子元素),如果它们本身既不是 flex、grid 也不是 table 容器
  • 多列容器(column-count 或 column-width (en-US) 值不为 auto,包括column-count 为 1)

BFC的作用

In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the ‘margin’ properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.

In a block formatting context, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box’s line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).

上面的意思是:
同一个BFC中,每个盒子都会在垂直方向上一个接一个排列,竖直距离由 margin 决定,相邻外边距会折叠为两个外边距中最大的一个。
每个盒子的左外边缘与包含该盒子父元素的左边缘相接触(从右往左排列的则是右外边缘与父元素的右边缘接触)。

也就是说,在一个BFC中,元素会按照BFC内定的规则去排列和摆放。

BFC解决相邻margin折叠问题

因为处于同一个BFC且有相邻的 margin则会造成折叠问题,所以只需要让其中一个处于不相同的BFC则可以解决折叠问题。

<html>
  <head>
  	<style>
  		.container {
    
    
		  overflow: auto; // 让 class 为 container 的块级元素产生新的 BFC 环境,则处于 container 形成的 BFC 中的 box1 则和处于由 html 形成的 BFC 环境的 box2 就是两个不相同的 BFC 所以折叠现象消失。
		}

		.box1 {
    
    
		  height: 200px;
		  width: 400px;
		  background-color: orange;

		  margin-bottom: 30px;
		}
		
		.box2 {
    
    
		  height: 150px;
		  background-color: purple;
		  
		  margin-top: 50px;
		}
  	</style>
  </head>
  <body>
  	<div class='container'> // BFC 环境是由 html 形成的
  	  <div class='box1'> // BFC 环境是由 container 形成的
  	  <div>
  	</div>
  	<div calss='box2'> // BFC 环境是由 html 形成的
  	</div>
  </body>
</html>

BFC解决float导致的高度塌陷问题

子元素 float 导致父级元素不能获取到子元素的高度,是因为子元素脱离了当前文档流,所以造成父元素的高度塌陷,而 BFC 则可以解决这个问题。但是 BFC 不能解决由定位引起的父元素高度塌陷问题!

<html>
  <head>
  	<style>
      .container {
    
    
        background-color: orange;
        
        overflow: auto; // 形成新的 BFC 来解决高度塌陷问题。前提条件是 container 高度为 auto 
      }

      .item {
    
    
        width: 400px;
        height: 200px;
        box-sizing: border-box;
        border: 1px solid black;
        float: left;
        background-color: red;
      }
    </style>
  </head>
  <body>
  	<div class="container">
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
    </div>
  </body>
</html>  

原理: 在 BFC 的高度为 auto 的情况下,按如下方法进行计算高度:

  1. 如果只有 inline-level,是行高的顶部和底部的距离;
  2. 如果有 block-level,是由最顶层的块上边缘和最底层块盒子的下边缘之间的距离;
  3. 如果有绝对定位元素,将被忽略;
  4. 如果有浮动元素,那么会增加高度以包括这些浮动元素的下边缘。

通过清除浮动来解决高度塌陷问题

<html>
  <head>
  	<style>
      .container {
    
    
        background-color: orange;
      }

      .item {
    
    
        width: 400px;
        height: 200px;
        box-sizing: border-box;
        border: 1px solid black;
        float: left;
        background-color: red;
      }

	  .clear_fix::after {
    
     // 清除浮动解决高度塌陷
	    content: '';
	    display: block;
	    clear: both;
	    height: 0;
	    visibility: hidden;
	  }
    </style>
  </head>
  <body>
  	<div class="container clear_fix">
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
    </div>
  </body>
</html>  

推荐视频:coderwhy面试题-01_CSS的BFC详细、权威、深入解析

猜你喜欢

转载自blog.csdn.net/qq_45488467/article/details/128858171