CSS之BFC(块级格式化上下文)

看了很多关于BFC的文章,就总结一下。终于应该算是明白了!css

其实要说BFC,就要说普通流(normal flow),就要说IFC(内联格式化上下文),在一块儿都说了,才能讲的明白。html

普通流说白了就是怎样把文档中的元素等自上而下一个一个的呈现出来,这些元素怎么在页面中摆放,而这个呈现过程就是普通流node

那么普通流是怎么样把页面布局呈现的呢?就是经过BFC和IFC,还有一个relative positioning(相对位移),今天重点讲解BFC和IFCweb

BFC名字很高大上,说白了就是一个规则,这个规则应用于块级元素(div,p)上。segmentfault

IFC这个规则应用于内联元素(span,em,i)上。ide

在文档呈现开始的时候,会自动建立一个BFC和IFC,来对整个页面进行布局,在没有咱们经过设置一些属性,来建立一个新的BFC的时候,整个文档就这一个BFC和IFC,因此全部的元素都要使用这个规则。布局

在普通流中,全部的盒子(不论是内联盒子(内联元素等)仍是块级盒子(块级元素等))都要属于一个格式化上下文,不是属于块级格式化上下文就是属于内联格式化上下文,可是不能同时属于二者,块级元素布局遵循块级格式化上下文的规则,内联元素布局遵循内联格式化上下文的规则来进行布局.就是这两个规则使得页面的全部元素有序的布局,才呈现出咱们所看到的web页面。网站

什么是BFC,IFCspa

BFC,IFC,就是控制元素如何进行布局。code

BFC规则:

1.若是给一个元素建立了一个BFC,就至关于建立了一个新的容器,容器内和容器外中的元素不会相互影响。外边的BFC规则,不会对容器里的BFC产生影响,而容器里面的BFC也不会对容器外的BFC产生影响,也就是相互隔绝,互不影响。

2.盒子的布局开始是从包含容器的顶部开始的。

3.同一个BFC中,在两个相邻的块级元素中,垂直margin会发生折叠

4.每一个盒子的左边界都要紧靠包含容器左边界(这也就解释了为何块级元素都是单独成一行的,若是不单独成行,第二个盒子的左边界怎么紧靠包含容器的左边界);

这第四个是最重要的布局规则

IFC规则:

1.盒子是水平一个接一个的排列,水平的margin,内边距,边框是能够有的。

2.垂直方向的对齐,多是底部对齐,顶部对齐,也多是基线对齐(这个是默认的);ps.这里的盒子应该是指的内联元素的盒子(span,strong等)和匿名内联盒子(只有文本,没有内联元素包含,自动建立的),他们合称内联盒子,一个或者多个内联盒子组成一个行框,行框的宽度由包含块和出现的浮动决定的(为何有浮动呢,后面解释);行框的高度决定看个人这篇文章(css之line-height);必定要分清楚,行框和内联盒子的关系,要否则我所说的你就不太可能理解

3.行框中的内联盒子的高度小于行框的高度时,内联盒子的垂直方向的对齐方式取决于vertical-align属性

4.当一个行框水平不能容纳内联盒子时,他们将会在垂直方向上产生多个行框,他们上下一个挨着一个,可是不会重叠

5.通常来讲,行框的左边界紧挨着包含容器的左边界,行框的右边界紧挨着包含容器的右边界,(是两个边都紧挨着)。然而,浮动盒子可能存在于包含边框边界和行框边界之间(后面解释这种状况);

6.多个内联盒子的宽度小于包含他们的行框时,他们在水平方向的分布取决于text-align属性(默认是left)

能产生新的BFC的属性:

1.float的值不为none。
2. overflow的值不为visible。
3.display的值为table-cell, table-caption, inline-block中的任何一个。
4.position的值不为relative和static。

只要给元素设置这些属性,则这些元素容器就不受外面的BFC约束了,他会给本身和他包含的元素应用新的BFC。也就是如今这些BFC分庭抗礼,你管不着我,我管不着你,只是咱们两个的BFC规则是同样的。

若是你上面这些没有看懂的话,经过代码必定能看懂。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
    <style>
    body,div{
        margin:0;
        padding:0;
    }
        #box1,#box2,#box3{
            width:100px;
            height:110px;
            border: 1px solid red;
        }
        #box4{
            width:500px;
            border:1px solid red;
            height:100px;
        }
        #box4Child{
            width:100px;
            height: 50px;
            border: 1px solid black;
            float:left;
        }
    </style>
</head>
<body>
    <div id="box1"></div>
    <div id="box2"></div>
    <div id="box3">
        <span>我是内联元素盒子</span>我是内联匿名元素盒子<em>我也是内联元素盒子</em>
    </div>
    <div id="box4"><div id="box4Child"></div><span>我是内联元素盒子</span>我是内联匿名元素盒子<em>我也是内联元素盒子</em></div>
</body>
</html>

文档解析我就从body开始提及,我就形象一点说,

1.当普通流碰见body元素时,一看你是块级元素,应用BFC规则,因此,你要从你包含容器html元素顶部开始,左边紧靠他的左边,因而body就布局好了

2.接下来就是body里面的的box1了,普通流一看,你也是块级元素,你也要应用BFC规则,由于你是第一个body的第一个元素,因此从body容器的顶部开始布局,你的左边也要紧靠body的左边,而且你后面的元素要距离你10px,因而乎,box1就布局好了

3.box2开始了,box2跟普通流说你看box1宽度才100px,你让我在他后面吧,咱们两个在一行才200px,普通流说不行,BFC的规则是你的左边必须紧靠包含容器(body元素)的左边,因而乎box2就只能本身一行了,(这也就是解释了为何块级元素单独成行),普通流说你看你的margin-top和box1的margin-bottom是相邻的,根据BFC大家必须折叠,因而他们两个之间的距离就10px,而不是20px;

4.同理,box3跟相似上面的,因而box3就布局好了;

5.如今进行box3的内部了,IFC说,span是内联元素应该应用个人规则,我先建立一个行框(行框是他的左边挨着包含框的左边,右边挨着包含框的右边),这时发现一个行框过小,不能包含的了这个内联盒子,因而,就在下面又建立了一个行框,来包含这个内联盒子。此次两个行框终于把span内联盒子装下了,接下来是又是一个盒子,此次是个匿名内联盒子,既然都是内联的,就挨着span内联盒子继续吧,发现也是放不下,就又建立了一个内联盒子,下面的em也是那样我就不说了,balabala。

6. 接下来开始布局box4,一看是块级元素就使用BFC。

7. 进行box4内部布局,一看是块级元素可是呢她又有float属性,这是就建立一个新的BFC,这时就不受BFC规则的约束了。就不须要独占一行等规则了,可是呢,这又牵扯到float布局定位机制,float的一些特性,float是这样的,好比设置左浮动,那么它的左边必定要紧挨着包含元素的左边或者是另外一个浮动元素的右边。多了我就不说了,看官方文档。这时box4child就布局好了,接下来就布局后面的东西了,一看是一个内联元素,好吧,就建立一个行框,这时要注意了上面IFC规则的第五条的后半部分,也就是说,如今在这里,这个行框的左边界不在紧挨着包含块的左边界了他也是能够挨着浮动元素的边界的,因而就产生了图中的效果,后面的东西同理上面就很少说了。

仅仅是我的理解,若有不对欢迎指正交流!

 

ps。以前写了一个爬取指定网站的算是小爬虫吧,使用nodejs写的,里面我添加了爬取博客园,csdn的关于web的版块,segmentfault问答,segmentfault文章,百度贴吧的JavaScript吧,w3ctech,w3cfuns等,我也就常去这几个网站了。界面我就以简洁为主。如今我就一直使用它来看文章,主要是简单快捷方便;地址:小爬虫

 W3C官方文档:http://www.w3.org/TR/CSS21/visuren.html#normal-flow

css定位机制之一:普通流

相关文章
相关标签/搜索