面试官:讲讲BFC和IFC

197 阅读4分钟

BFC

Block fomatting context ,块级格式上下文,是一个独立的渲染区域,区域与外部毫不相干。

创建方式

  • 根元素(<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)
  • display 值为 flow-root 的元素
  • overflow 值不为 visible、clip 的块元素
  • contain 值为 layout、content 或 paint 的元素
  • 弹性元素(display 值为 flex 或 inline-flex 元素的直接子元素),如果它们本身既不是 flexgrid 也不是 table 容器
  • 网格元素(display 值为 grid 或 inline-grid 元素的直接子元素),如果它们本身既不是 flexgrid 也不是 table 容器
  • 多列容器(column-countcolumn-width(en-US) 值不为 auto,包括column-count 为 1)
  • column-span 值为 all 的元素始终会创建一个新的 BFC,即使该元素没有包裹在一个多列容器中 (规范变更, Chrome bug)

布局规则

  • 1 内部的盒子会在垂直方向,一个个地放置;
  • 2 BFC是页面上的一个隔离的独立容器;
  • 3 属于同一个BFC的 两个相邻Box上下margin会发生重叠 ;
  • 4 计算BFC的高度时,浮动元素也参与计算
  • 5 每个元素的左边,与包含的盒子的左边相接触,即使存在浮动也是如此;
  • 6 BFC的区域不会与float重叠;

应用

包含内部浮动

<!-- BFC-包含内部浮动 -->
			<section>
			  <div class="box">
			    <div class="float">I am a floated box!</div>
			    <p>I am content inside the container.</p>
			  </div>
			</section>
			<section>
			  <div class="box" style="overflow:auto">
			    <div class="float">I am a floated box!</div>
			    <p>I am content inside the <code>overflow:auto</code> container.</p>
			  </div>
			</section>
			<section>
            //flow-root在块级布局方式的基础上对子元素的浮动float属性进行了修正
			  <div class="box" style="display:flow-root">
			    <div class="float">I am a floated box!</div>
			    <p>I am content inside the <code>display:flow-root</code> container.</p>
			  </div>
			</section>
section {
  height: 150px;
}
.box {
  background-color: rgb(224, 206, 247);
  border: 5px solid rebeccapurple;
}
.box[style] {
  background-color: aliceblue;
  border: 5px solid steelblue;
}
.float {
  float: left;
  width: 200px;
  height: 100px;
  background-color: rgba(255, 255, 255, .5);
  border:1px solid black;
  padding: 10px;
}

排除外部浮动

<section>
  <div class="float">Try to resize this outer float</div>
  <div class="box"><p>Normal</p></div>
</section>
<section>
  <div class="float">Try to resize this outer float</div>
  <div class="box" style="display:flow-root"><p><code>display:flow-root</code><p></div>
</section>
section {
  height:150px;
}
.box {
  background-color: rgb(224, 206, 247);
  border: 5px solid rebeccapurple;
}
.box[style] {
  background-color: aliceblue;
  border: 5px solid steelblue;
}
.float {
  float: left;
  overflow: hidden; /* required by resize:both */
  resize: both;
  margin-right:25px;
  width: 200px;
  height: 100px;
  background-color: rgba(255, 255, 255, .75);
  border: 1px solid black;
  padding: 10px;
}

阻止外边距重叠

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

.blue {
  background: blue;
}

.red-outer {
  overflow: hidden;
  background: red;
}

IFC

inline fomatting context,行内格式化上下文。

布局规则

  • 子元素水平方向横向排列,并且垂直方向起点为元素顶部。
  • 子元素只会计算横向样式空间,【padding、border、margin】,垂直方向样式空间不会被计算,【padding、border、margin】。
  • 在垂直方向上,子元素会以不同形式来对齐(vertical-align)
  • 能把在一行上的框都完全包含进去的一个矩形区域,被称为该行的行框(line box)。行框的宽度是由包含块(containing box)和与其中的浮动来决定。
  • IFC中的“line box”一般左右边贴紧其包含块,但float元素会优先排列。
  • IFC中的“line box”高度由 CSS 行高计算规则来确定,同个IFC下的多个line box高度可能会不同。
  • 当 inline-level boxes的总宽度少于包含它们的line box时,其水平渲染规则由 text-align 属性值来决定。
  • 当一个“inline box”超过父元素的宽度时,它会被分割成多个boxes,这些 boxes 分布在多个“line box”中。如果子元素未设置强制换行的情况下,“inline box”将不可被分割,将会溢出父元素。

应用

解决元素垂直居中

多个文本元素行高不一致排列混乱

float元素优先排列(在文章段落开头添加“tag”可以用到)

多个元素水平居中(水平排列规则根据IFC容器的text-align值来排列,可以用来实现多个子元素的水平居中)