BFC块级格式化上下文

一、BFC概念介绍

定义:BFC, 全称是block formatting context,它是一个独立封闭的渲染区域,在这个区域内的所有元素,从区域的顶部起,一个接一个地根据自身的布局特性进行排列:在这个区域内的块级元素 ,按从上到下的顺序显示,相邻的块级元素可以使用margin隔离,但在垂直方向上相邻的块级元素会发生margin合并;在这个区域内的inline-level或inline-block-lever元素,则按从左到右的顺序显示(W3C组织说BFC内部的元素都是一个接一个地垂直显示,我觉得不是很严格,因为BFC内部也可以容纳inline-level和inline-level-block元素,所以这里我的解释和W3C还是稍微有一些不一样)具有BFC格式化环境的元素,我们称之为BFC元素,可以说,BFC定义了BFC元素content区域的渲染规则。

对于上述概念中提到的inlne-lever,inline-block-lever,作如下知识扩展。

从元素的布局特性来分,主要可以分为三类元素:block-level(块级)元素、inline-level(行内级)元素和inline-block-level(行内块级)元素,我们可以对其下个定义:

1. 块级元素

display属性取block、table、flex、grid和list-item等值的独占一行显示的元素。

2. 行内级元素

display属性取inline值的可在同一行内排列显示的元素。

3. 行内块级元素

display属性取inline-block、inline-table、inline-flex和inline-grid等值的兼具块级元素和行内级元素布局特性的元素。行内块级元素兼具block-level元素和inline-level元素的布局特性,主要体现为:

排列方式与行内级元素同,不独占一行,在一行内按从左到右的顺序排列;

水平和垂直方向上的对齐方式与行内级元素同;

和块级元素一样,可以设置任何尺寸属性(但width默认为0);

更通俗一点

块级元素 <div>,h1~h6,<li>,<dt>,<dd>,<p>,<form>,<table>等
行内元素 <a>,<abbr>,<em>,<i>,<span>,<strong>等
行内块元素 <img>,<input>,或者其它利用display:inline-block转换过来的行内块元素

(1)块级元素可以嵌套行内元素和某些块级元素。

(2)行内元素不能嵌套块级元素,可以嵌套文本和其它行内元素。

(3)二者的不同:属性不同,主要是盒模型属性上:行内元素设置width无效,height无效(可以设置line-height),margin上下无效,padding上下无效。

(4)行内元素和块元素之间的转换:

display

块元素默认display:block;
行内非替换元素(a,span)默认为display:inline;
行内替换元素(input)默认为display:inline-block;

display:none;不显示该元素,也不会保留该元素原先占有的文档流位置。
display:block;转换为块级元素。
display:inline;转换为行内元素。
display:inline-block;转换为行内块级元素。
float
当把行内元素设置完float:left/right后,该行内元素的display属性会被赋予block值,且拥有浮动特性。行内元素去除了之间的莫名空白。
position
当为行内元素进行定位时,position:absolute与position:fixed.都会使得原先的行内元素变为块级元素。
(5)inline-block 的元素(如input、img)既具有 block 元素 可以设置宽高的特性,同时又具有 inline 元素默认不换行的特性
对于上文提到的行内替换元素和行内非替换元素,作如下扩展:
行内级元素的分类,其可再细分两类元素:

1)可置换行内元素

在MDN中,其对“可置换行内元素”的定义如下:

按字面翻译,“可置换行内元素”,是展示内容不在CSS作用域内的元素。这句话是不是不好理解?我们可以换另外一种方式理解:“可置换行内元素”,是这样一类元素,其展示的内容是通过元素的src、value等属性或CSS content属性从外部引用得到的,可被替换的。随着内容来源或内容数量的变化,可置换元素本身也会有水平和垂直方向上尺寸的变化。典型的可替换元素有 <img>、 <object>、 <video> 和 <embed>,表单类的可替换元素有<textarea> 和<input> ,某些元素只在一些特殊情况下表现为可替换元素,例如 <audio> 、<object><canvas><applet>

特别地,通过 CSS content 属性来插入的对象又被称作 匿名可置换元素。

2)不可置换行内元素

不可置换行内元素”其实就是我们常见的一类行内元素,这一类行内元素有<a><span>等。“不可置换行内元素”是相对于“可置换行内元素”的,其展示的内容是在CSS作用域范围内的,是不可替换的。

 

行内级元素有如下几个布局特性:

  1. 在一行内可以与多个同类型的元素按从左到右的顺序排列;

  2. 不可置换行内元素不能设置width、height和垂直方向上的margin,而可置换行内元素则可以;

  3. 在水平和垂直方向上的对齐方式,行内级元素分别受父元素的text-align属性和自身vertical-align属性的控制(父元素是table-cell元素时,也受父元素的vertical-align属性控制),在水平方向上默认左对齐,在垂直方向上默认在行框的baseline基线上显示(“行框”的概念,会在后面深入讲解);

二、创建BFC

1、创建BFC元素的方式有如下几种(摘自MDN BFC):

  • 根元素或其它包含它的元素

  • 浮动元素 (元素的 float 不是 none)

  • 绝对定位元素 (元素的 position 为 absolute 或 fixed)

  • 内联块 (元素具有 display: inline-block)

  • 表格单元格 (元素具有 display: table-cell,HTML表格单元格默认属性)

  • 表格标题 (元素具有 display: table-caption, HTML表格标题默认属性)

  • overflow 值不为 visible 的块元素

  • display: flow-root

  • contain为以下值的元素: layoutcontent, 或 strict

  • 弹性项 (display: flex 或 inline-flex元素的子元素)

  • 网格项 (display: grid 或 inline-grid 元素的子元素)

  • 多列容器 (元素的 column-count 或 column-width 不为 auto, 包括 column-count: 1的元素)

  • column-span: all 应当总是会创建一个新的格式化上下文,即便具有 column-span: all 的元素并不被包裹在一个多列容器中。

2、BFC元素特性:

 (1)对应一个独立、封闭的渲染区域,子元素的CSS样式不会影响BFC元素外部;

 (2)浮动子元素参与BFC父元素的高度计算,也就是BFC元素能够识别浮动元素(将元素声明为BFC元素,也是clearfix解决父元素塌陷问题的一种常用方法);

(3)占据文档流的BFC元素(可使用overflow: auto创建),能够识别浮动的兄弟元素;

 (4)占据文档流的BFC元素(可使用overflow: auto创建),width为auto时,会占满当前行的剩余宽度;

除了使用overflow来创建BFC之外,还有一些CSS属性也可以创建BFC。比如上面我们所看见的,浮动一个元素也可以为该元素创建BFC,浮动元素会包裹它内部的所有元素。还有以下几种方式也可以创建BFC:

  • 使用position:absolute或者position:fixed

  • 使用display:inline-blockdisplay:table-cell或者display:table-caption,其中table-celltable-caption是表格相关元素对应默认CSS值,所以当你创建表格时,每个表格的单元格都会自动创建BFC

  • 另外当使用多列布局时,使用了column-span:all也可以创建BFC。Flexbox和Grid布局中的元素也会自动创建类似BFC的机制,只是它们被称为FFC(弹性格式上下文)和GFC(网格格式上下文)。这反映了它们所参与的布局类型。一个BFC表明他内部的元素参与了块级布避,一个FFC意味着它内部的元素参与了Flexbox布局。在实践中,这几种布局的结果是相似的,浮动元素会被包裹,外边距不会叠加。

3、创建BFC的新方式 display:flow-root

使用overflow或其他的方法创建BFC时会有两个问题。首先,这些方法本身是有自身的设计目的,所以在使用它们创建BFC时可能会产生副作用。例如,使用overflow创建BFC后在某些情况下可能会看到出现一个滚动条或者元素内容被裁切。这是由于overflow属性的设计是用来让你告诉浏览器如何定义元素的溢出状态的。浏览器执行了它最基本的定义。

另一个问题是,即使在没有出现副作用的情况下,使用overflow也可能会使另一个开发人员感到困惑。他们可能会各种猜想:

这里为什么要把overflow的值设置为autoscroll?原来的开发人员这样做的意义是什么?原来的开发人员是想让这里出现滚动条吗?最安全的做法应该是创建一个BFC时并不会带来任何副作用,它内部的元素都安全的呆在这个迷你布局中,这种方法不会引起任何意想不到的问题,也可以理解开发者的意图。CSS工作组也十分认同这种想法,所以他们定制了一个新的属性值:display:flow-root

你可以使用display:flow-root安全的创建BFC,来解决上文中提到的各种问题:包裹浮动元素、阻止外边距叠加和阻止围绕浮动元素。

(1)一旦BFC创建,它就会阻止它内部的元素逃离并从盒子里伸出来。

(2)一个BFC会停止去围绕浮动元素。你可能很熟悉BFC的这个特性,因为我们在有浮动元素的列类型布局中常用到。如果一个元素创建了BFC,它就不会去围绕(或者说包裹)任何浮动元素。

(3)BFC阻挡外边距叠加

(4) overflow之所以能够有效是因为当它的值是非visible时会创建一个BFC,而BFC的一个特性就是包裹浮动元素。

三、示例

左侧图片使用了float

右侧内容并没有如我们预料一样规整的排在右侧,而是将左侧图片包围起来。要使文字不要围绕图片排列,为右侧内容部分设置overflow:hidden属性来使它形成一个新的BFC:

.cont{margin:10px;color:#37a;overflow:hidden;}

第二个示例:实现两行两列的浮动布局

<div id="A" style="display:inline-block;">//创建了一个BFC
<div id="red" style="background: red;width: 100px;height: 100px;float: left;"></div>
<div id="orange" style="background: orange;width: 100px;height: 100px;float: left;"></div>
</div>
<div id="B">
<div id="yellow" style="background: yellow;width: 100px;height: 100px;float: left;"></div>
<div id="green" style="background: green;width: 100px;height: 100px;float: left;"></div>
</div>

由上述代码可以看出,BFC可以包含浮动元素。

运行结果如下:


参考文章:https://www.cnblogs.com/iceflorence/p/6626187.html?utm_source=itdadao&utm_medium=referral

点击打开链接

猜你喜欢

转载自blog.csdn.net/runner_123/article/details/80188306