整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

「css」BFC-块级格式化上下文的消化与吸收

「css」BFC-块级格式化上下文的消化与吸收

、BFC概念

先看官方定义:BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。

不愧是官方定义,看起来就不容易进脑子,下次面试被问到还是会挠头=.=。所以接下来我们先把这个东西拆开来看看,到底是什么神秘力量让它如此不羁。

1.1 拆分

块级:即我们常用的块级元素,eg:div、li、p等

格式化:每种代码都有自己的展现规则,格式化的作用就是把代码变美变漂亮,编程人员阅读起来更舒服。以后台返回的json为例:

{"success":true,"data":{"userid":"1","name":"Jack","mobile":"123456"},"errorMessage":"成功!","code":1}

格式化以后的数据格式应为:

{
    "success": true,
    "data": {
        "userid": "1",
        "name": "Jack",
        "mobile": "123456"
    },
    "errorMessage": "成功!",
    "code": 1
}

所以对于格式化的定义,可以简单地概括为根据制定的具体规则,对内容展示做一些处理,从而达成某些规范,或使内容更加美观合理。

上下文:表示格式化影响的范围,或者作用域。上例中的上下文即为该特定json代码段。

综上所述,我们可以这么理解BFC的概念,在正常的文档流中:

  • 满足一定条件下,一个普通的块级元素,就会变成一个块级格式化上下文
  • 在这个上下文范围内,所有的元素排列都会遵循一定的规则,即格式化的规则,进行排列布局。(且针对不同类型的元素会对应不同的规则)。
  • 这个范围内的元素不管如何布局都不会影响到上下文外部的元素,也就是一个独立的布局单位

1.2 创建BFC

一个普通的块级元素满足以下条件中的任意一个即可触发BFC(参考MDN):

  • 根元素(html)
  • 浮动元素(元素的 float 不是 none)
  • 行内块元素(元素的 display 为 inline-block)
  • 绝对定位元素(元素的 position 为 absolute 或 fixed)
  • 表格单元格(元素的 display 为 table-cell,HTML表格单元格默认为该值)
  • 表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值)
  • 弹性元素(display 为 flex 或 inline-flex 元素的直接子元素)
  • overflow 计算值(Computed)不为 visible 的块元素
  • 多列容器(元素的 column-count 或 column-width (en-US) 不为 auto,包括 column-count 为 1)
  • column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中


二、BFC应用场景

2.1 清除元素浮动

如下例子中,因为父元素未设置高度,并且子元素浮动脱离了文档流,所以父元素出现高度塌陷问题(子元素无法撑开父元素的高度),要解决这个问题,我们可以给父元素设置css属性触发BFC来解决,方式见1.2创建BFC,通常的做法是设置父元素的overflow为非默认的 visible 的值。

HTML

<div class="box">
    <div class="float fl">左浮动元素</div>
    <div class="float fr">右浮动元素</div>
</div>

CSS

.box {
        background-color: #eee;
        border: 5px solid red;
    }

.float {
  width: 200px;
  height: 150px;
  background-color: white;
  border:3px solid black;
  padding: 10px;
}  
.fl {
  float: left;
} 
.fr {
  float: right;
}  


无BFC,高度塌陷


给父元素box添加属性 overflow: hidden; 触发BFC后,浮动的子元素也遵守流布局了:


触发BFC,高度正常


2.2 外边距合并(重叠)

HTML

<div class="box">
    <div class="item top"></div>
    <div class="item bot"></div>
</div>

CSS

.box {
  	background-color: #eee;
  	border: 5px solid red;
  	overflow: hidden;
}
.item {
  	width: 200px;
  	height: 150px;
  	background: lightblue;
}  
.top {
  	margin-bottom: 50px;
} 
.bot {
  	margin-top: 50px;
} 

外间距重叠只有50px

要消除外边距合并,可以通过给相邻元素的其中之一,进行一层BFC隔离封装:

<style>
  .item-box {
      overflow: hidden;
  }
 </style>
<div class="box">
    <div class="item top"></div>
    <div class="item-box">
      <div class="item bot"></div>
    </div>
</div>

外间距正常,为50+50=100px

以上。

. 如何理解CSS盒子模型

标准盒子模型:宽度=内容的宽度(content)+ border + padding

低版本IE盒子模型:宽度=内容宽度(content+border+padding)

2.BFC

1. 如何理解CSS盒子模型标准盒子模型:宽度=内容的宽度(content)+ border + padding低版本IE盒子模型:宽度=内容宽度(content+border+padding)

2.BFC

1)什么是 BFC

BFC(Block Formatting Context)格式化上下文,是 Web 页面中盒模型布局的 CSS渲染模式,指一个独立的渲染区域或者说是一个隔离的独立容器。

2)形成 BFC 的条件

* 浮动元素,float 除 none 以外的值

* 定位元素,position(absolute,fixed)

* display 为以下其中之一的值 inline-block,table-cell,table-caption

* overflow 除了 visible 以外的值(hidden,auto,scroll)

3)BFC 的特性

* 内部的 Box 会在垂直方向上一个接一个的放置。

* 垂直方向上的距离由 margin 决定

* bfc 的区域不会与 float 的元素区域重叠。

* 计算 bfc 的高度时,浮动元素也参与计算

* bfc 就是页面上的一个独立容器,容器里面的子元素不会影响外面元素。

3.标签语义化

代码结构更加清晰

见名知意,没有基础的人也能知道这部分代码是干嘛的

方便团队开发维护,代码可读性更强

有利于SEO优化,爬虫依赖于标签来确定上下文关系

4.meta标签

meta标签提供关于html文档的元数据,不会显示在页面,但是对于机器是可读的,告诉浏览器怎么解析页面,告诉搜索引擎关键字(SEO优化)

meta作用:告诉机器浏览器该如何解析该页面,描述这个页面的主要内容,可以设置服务器发送到浏览器的http头部内容

charset="utf-8"设置页面使用的字符编码

viewport 设置视口,移动端的适配

5.css与javascript引入设置script标签的引入一般放在body最后,这样避免脚本过大,加载时间长,导致页面长时间空白,

这是因为渲染进程与js进程是互斥的,脚本会阻塞页面的渲染,脚本之间的加载是同步进行的,按引入顺序执行,但是以下两个属性会影响脚本执行与页面渲染的顺序

defer:不会阻塞渲染,这样即使放在header内部,也不会阻塞页面加载,不过js会先于document加载完成,并且也不会影响脚本之间的执行顺序,按照引入顺序执行

async:与defer一样,都是解决阻塞渲染,但它是在document加载完成后才执行,并且它的执行顺序是按照谁先加载完成执行谁,所以对于文件顺序有要求,存在前后依赖的不要使用它

6.HTML的块级元素,行内元素,行内块元素有哪些,区别是什么

块级元素:div,h1-h6,p,ul,ol,dl,li,hr,dt,dd,form,table

特性:块元素独占一行,宽高生效,默认宽和父元素一样,内容撑开高度,margin,padding全部生效

行内元素:em,i,del,small,strong,ins,span,a

特性:宽高不生效,左右margin生效上下不生效,在一行排列,大小靠内容撑开,padding都生效

行内块元素:img,input(表单元素,除去form)

特性:在一行排列,宽高生效,margin,padding生效

7.CSS3有哪些新特性

border-radius圆角

border-image 边框图片

border-image: url() top right bottom left

border-width: top right bottom left

box-shadow盒子阴影: x,y,size,opcity

text-shadow文字阴影linear-gradient 线性渐变

background: linear-gradient(to position , color,color,...,color)

radial-gradient 径向渐变

background: radial-gradient(shap size at position ,

color,color,...,color)

2D/3D转换 transform:rotate(旋转) scale(缩放) translate(位移)

@media媒体查询,根据屏幕宽度,设置,用来解决移动端适配,根据屏幕大小使相应的css生效

flex布局(弹性盒子)

8.实现元素隐藏

display:none 不占位,源码可见

opacity: 0 占位,源码可见,透明度0

visibility: hidden 占位,源码可见

position: top:-9999px,left:-9999px 利用定位将元素移出视窗

9.如何实现元素水平居中

行内元素:text-align:center

块元素: margin: 0 auto

position: left: 50%; transform: translate(-50%)

10.如何实现元素垂直居中

height=line-height

verticle-align: middle

position: top: 50%; transform: translate(0,-50%)

11.Position

static 默认

relative 相对定位,不脱标,相对于自身位置进行偏离,不影响元素本身特性,z-index提升层级

absolute 绝对定位,脱标,相对于已有定位的父元素进行偏离,都没有就相对于body进行偏离

fixed 固定定位,脱标,相对于视窗进行偏离

12.定位元素水平垂直居中

宽高固定 position: top:0,left:0,right:0,bottom:0,margin:auto

宽高固定 position:top: 50%, left: 50%, margin-left: -width/2px,margin

top: -height/2px

dispaly: flex; justify-content: center,align-items: center(极力推荐)

position: left: 50%,top: 50%; transform: translate(-50%,-50%)

13.清除浮动

不清楚浮动会发生高度塌陷:浮动元素父元素高度自适应(父元素不写高度时,子元素写了浮动后,父元素会发生高度塌陷)

* clear清除浮动(添加空div法)在浮动元素下方添加空div,并给该元素写css样式:

{clear:both;height:0;overflow:hidden;}

* 给浮动元素父级设置高度

* 父级同时浮动(需要给父级同级元素添加浮动)

* 父级设置成inline-block,其margin: 0 auto居中方式失效

* 给父级添加overflow:hidden 清除浮动方法

* 万能清除法 after伪类 清浮动(现在主流方法,推荐使用)

.float_div:after{
		 content:".";
 			clear:both;
 			display:block;
       height:0;
 			overflow:hidden;
			 visibility:hidden;
}
.float_div{
			 zoom:1
}

14.css选择器有哪些,选择器的优先级

- id选择器

- 类选择器

- 属性选择器

- 伪类选择器

- 标签选择器

- 伪元素选择器

- 通配符选择器优先级:内联样式 > ID选择器(100)> 类选择器(10)=属性选择器=伪类选择器 > 元素选择器(1)=关系选择器=伪元素选择器 > 通配符选择器(0)

!important

后代选择器选全部

子代选择器只选亲孩子

15.各种布局的优缺点

1. float 布局

优点: 比较简单,兼容性也比较好。只要清除浮动做得好,是没有什么问题的缺点:浮动元素是脱离文档流,要做清除浮动,这个处理不好的话,会带来很多问题,比如高度塌陷等。

2. 绝对布局

优点:很快捷,设置很方便,而且也不容易出问题缺点:绝对定位是脱离文档流的,意味着下面的所有子元素也会脱离文档流,这就导致了这种方法的有效性和可使用性是比较差的。

3. flex 布局

优点:简单快捷缺点:不支持 IE8 及以下

4. table布局

优点:实现简单,代码少缺点:当其中一个单元格高度超出的时候,两侧的单元格也是会跟着一起变高的,而有时候这种效果不是我们想要的。

5. grid布局

跟 flex 相似。

16.html5有哪些新特性、移除了那些元素?如何处理HTML5新标签的浏览器兼容问题?如何区分 HTML 和 HTML5?

**新特性:**

HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。

拖拽释放(Drag and drop) API

语义化更好的内容标签(header,nav,footer,aside,article,section)

音频、视频API(audio,video)

画布(Canvas) API

地理(Geolocation) API

本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失;

sessionStorage 的数据在浏览器关闭后自动删除

表单控件,calendar、date、time、email、url、search

新的技术webworker, websocket, Geolocation

**移除元素:**

纯表现的元素:basefont,big,center,font, s,strike,tt,u;

对可用性产生负面影响的元素:frame,frameset,noframes;

**h5新标签兼容:**

IE8/IE7/IE6支持通过document.createElement方法产生的标签,

可以利用这一特性让这些浏览器支持HTML5新标签,

当然最好的方式是直接使用成熟的框架、使用最多的是html5shim框架

<!--[if lt IE 9]><script> src="http://html5shim.googlecode.com/svn/trunk/html5.js"
</script>
<![endif]-->


**如何区分:**

DOCTYPE声明\新增的结构元素\功能元素

17. CSS3新增伪类举例:

p:first-of-type 选择属于其父元素的首个 <p> 元素的每个 <p> 元素。

p:last-of-type 选择属于其父元素的最后 <p> 元素的每个 <p> 元素。

p:only-of-type 选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。

p:only-child 选择属于其父元素的唯一子元素的每个 <p> 元素。

p:nth-child(2) 选择属于其父元素的第二个子元素的每个 <p> 元素。

:enabled :disabled 控制表单控件的禁用状态。

:checked 单选框或复选框被选中。

18.解释盒模型宽高值的计算方式,边界塌陷,负值作用,box-sizing概念?

1. 盒模型:IE 678 下(不添加doctype) 使用ie盒模型,宽度=边框 + padding + 内

容宽度; chrom、IE9+、(添加doctype) 使用标准盒模型, 宽度=内容宽度。

2. box-sizing : 为了解决标准黑子和IE盒子的不同,CSS3增添了盒模型属性box-sizing,content-box(默认),border-box 让元素维持IE传统盒子模型, inherit 继承父盒子模型;

3. 边界塌陷:块元素的 top 与 bottom 外边距有时会合并(塌陷)为单个外边距(合并后最大的外边距),这样的现象称之为 外边距塌陷。

4. 负值作用:负margin会改变浮动元素的显示位置,即使我的元素写在DOM的后面,我也能让它显示在最前面。

19.如何实现浏览器内多个标签页之间的通信?

调用localstorge、cookies等本地存储方式

20.解释下浮动和它的工作原理?清除浮动的方法

浮动元素脱离文档流,不占据空间。浮动元素碰到包含它的边框或者浮动元素的边框停留。

1.使用空标签清除浮动。

这种方法是在所有浮动标签后面添加一个空标签 定义css clear:both. 弊端就是增加了无意义标签。

2.使用after伪对象清除浮动

该方法只适用于非IE浏览器。具体写法可参照以下示例。使用中需注意以下几点。一、该方法中必须为需要清除浮动元素的伪对象中设置 height:0,否则该元素会比实际高出若干像素;

#parent:after{
		content:".";
		height:0;
		visibility:hidden;
		display:block;
		clear:both;
}

3.设置overflow为hidden或者auto

4.浮动外部元素

SS是web前端中的重要内容,很多初学者在学习CSS时都会遇到各种各样的问题,今天就给大家分享web前端开发如何理解CSS不惧和块级格式化上下文。也许你从未听说过这个术语,但是如果你曾经用 CSS 做过布局,那么你也许知道它是什么。理解什么是 BFC ,它为什么会起作用以及如何创建一个有用的 BFC 可以帮助你理解 CSS 布局是怎样工作的。

什么是BFC?

最容易明白一个 BFC 表现的是一个浮动的例子。在下面的例子中有一个盒模型,其中包含一张左浮动的图和一些文字。如果我们有大量的文字,它环绕在浮动的图像上,则边框会围绕着整个区域。

<div class="outer">
<div class="float">I am a floated element.</div>
I am text inside the outer box.
</div>
.outer {
border: 5px dotted rgb(214,129,137);
border-radius: 5px;
width: 450px;
padding: 10px;
margin-bottom: 40px;
}
.float {
padding: 10px;
border: 5px solid rgba(214,129,137,.4);
border-radius: 5px;
background-color: rgba(233,78,119,.4);
color: #fff;
float: left;
width: 200px;
margin: 0 20px 0 0;
}



图1:文本环绕着浮动元素

如果删除了一些文本,那么文本就不足以环绕图像,并且因为图片浮动脱离了文档流,边框就会在图片下面并且上升到文本的高度。

图2:没有足够的文本,边框就不能到达浮动元素所期望的高度

这是因为当我们在浮动一个元素时,文本所在的盒模型仍然是固定的高度,而因浮动元素而缩短的空间是文本的行框。这就是为什么背景和边框会出现在浮动元素的后面。

这里有两种我们通常修复这种问题的方式。一种是使用清除浮动 clearfix hack[1],它是通过在文本和图片下面插入一个元素并且设置清除两侧浮动来起作用的。另一种方式是使用 overflow属性,使用其他的值来代替默认的 visible 。

.outer {
overflow: auto;
}

图3:使用 overflow:auto 使盒模型中包含浮动

overflow 属性起作用的原因是使用任何一个其他值来代替初始值 visible ,从而创建一个BFC。即 BFC 的一个特点就是它包含浮动。

BFC 布局是一个迷你布局

你可以认为 BFC 在网页中是一个迷你布局。一旦一个元素创建的 BFC ,所有东西都包含在里面了。正如我们所看到的,它包含浮动元素使其不再超出盒子底部。同时 BFC 也产生了一些其他有用的行为。

BFC 防止外边距塌陷

理解外边距塌陷是另一个被低估的 CSS 技能。在下一个例子中,有一个灰色背景的 div 。这个 div 中有两个段落。外层 div 有 40px 的下边距;每一个段落也分别有 20px 的上下边距。

.outer {
background-color: #ccc;
margin: 0 0 40px 0;
}
p {
padding: 0;
margin: 20px 0 20px 0;
background-color: rgb(233,78,119);
color: #fff;
}

由于 p 元素的外边距和外层 div 的外边距之间没有任何东西而导致它们折叠,使 p 段落最后会与盒子的顶部和底部平齐。所以在 p 段落的上面和下面我们没有看到任何灰色。

图4:外边距塌陷导致在盒子的顶部和底部看不到任何灰色

如果我们对盒模型应用 BFC ,那么它将包括段落和边距并使之不会塌陷,所以我们将在边距的后面看到灰色的背景。

.outer {
background-color: #ccc;
margin: 0 0 40px 0;
overflow: auto;
}

图5:使用BFC外边距将不会塌陷

BFC 再一次使元素包含在其中,阻止其外边距塌陷或超出盒模型。

BFC 阻止内容环绕浮动元素

你也会熟悉 BFC 这种行为,就是它如何在使用浮动的多列布局中工作的。如果一个项目创建了 BFC ,那么它将不会环绕任何浮动元素,比如在下面的示例中有这样的标记:

<div class="outer">
<div class="float">I am a floated element.</div>
<div class="text">I am text</div>
</div>

带有 float 类的元素开始浮动,然后 div 中的文本会环绕在浮动元素周围。

图6:文本环绕浮动元素

那么可以使用通过对文本使用 BFC 来阻止其环绕行为。

.text {
overflow: auto;
}

图7:div 包含的文本使用了 BFC 使之停止环绕

这是我们创建多列浮动布局常用的方式。浮动一个元素同时也为另一个元素创建了 BFC ,所以当右边的元素比左边高时,创建的列也不再尝试环绕对方。

还有什么方式可以创建 BFC?

除了使用 overflow 属性以外,其他一些 CSS 属性也可以创建 BFC 。正如我们看到的,浮动一个元素也创建了 BFC ,所以浮动项目将包含里面的任何元素。

其他方式还有使用 position: absolute ,position: fixed ,使用 display: inline-block , display: table-cell 及 display: table-caption ,其中 table-cell 以及 table-captions 是 HTML 元素的默认属性,所以如果有一个 table 数据,那么它的每个格子都将创建 BFC 。 column-span: all 多被使用在多列布局中。

Flex 和 Grid 项目也会创建类似的 BFC ,它们分别被描述为 Flex 格式化上下文和 Grid 格式化上下文,这分别反映了不同的布局类型。 BFC 表示块级布局, FFC 代表 Flex 布局。在实际项目中结果是一样的,都是包含浮动并且外边距不会发生塌陷。

创建 BFC 新方式

使用 overflow 属性或其他方式创建 BFC 有两个问题。第一,这些方法对于它们真正的用途会产生副作用。使用 overflow 属性创建一个 BFC 并且包含浮动,但是在某些情况下你可能会发现得到一个了不必要的滚动条,或者阴影被剪掉了。这是由于 overflow 属性本质上是告诉浏览器在溢出的情况下应该怎样做—产生滚动条或者剪掉元素。浏览器实际上做了你让它做的工作!

即使在没有任何副作用的情况下,使用 overflow 属性也可能会让另一个开发人员感到困惑。为什么 overflow 属性设置为自动或滚动?开发者最初的目的是什么?他们希望在这个组件上使用滚动条吗?怎样创建一个 BFC 是行之有效的?应该是没有造成其他行为而创造出迷你的布局, 或者保证是在安全范围内的,它将不会引发任何意想不到的问题,并且开发人员的意图也很清晰。

CSS 工作组认为有一个很方便的新的 display 属性: flow-root 。

你可以在任何情况下使用 display: flow-root ,它将会创建一个新的有用的 BFC ,它包含浮动,阻止外边距塌陷,并且阻止元素环绕浮动。

你可以在下面的 CodePen 中看到上述所有的这些, 如果你的浏览器支持 display: flow-root 的话,如目前流行的火狐或谷歌浏览器。

图8:支持 display: flow-root 属性的浏览器

支持这个属性的浏览器是有限的,但如果你认为这将是方便的,你可以去支持它。然而,即使目前你不能够在你的代码很流利的使用 flow-root 功能,但你现在明白了 BFC 是什么,以及当你使用 overflow 属性或其它方法包含浮动的时候你明白了你在做什么。了解这样一个事实:比如 BFC 将阻止元素环绕浮动,这在不支持的浏览器中想创建 Flex 或 Grid 布局的时候都是非常有用的。

你已经了解了一些关于浏览器如何布置 Web 页面的基本原理,这看起来似乎无关紧要,但却可以加快创建和调试 CSS 布局的时间。关注“武汉千锋”公众号,可以获取更多web前端学习资料。