码迷,mamicode.com
首页 > 其他好文 > 详细

DOM节点渲染详解--盒子的生成到布局过程

时间:2016-04-22 20:17:22      阅读:250      评论:0      收藏:0      [点我收藏+]

标签:

CSS的可视化格式模型是一种处理文档并把它显示在可视化媒介中的一种算法。它是CSS的基本概念,可视化格式模型转化每个文档元素,生成0个或一个或多个符合CSS盒子模型规则的盒子。每个盒子的布局受如下几点影响:
1. 盒子的大小;
2. 盒子的类型;
3. 定位的方案;
4. 它的子代和兄弟;
5. 可视区域和位置;
6. 它包含的图片的已有大小;
7. 其他额外的信息;

特定的模型渲染每个盒子,这个模型与包含这个盒子的块相关。通常,一个盒子为他的后代元素建立一个包含块,除非这个盒子不受包含块的约束,比如一个盒子的布局超出了包含块,这也叫做溢出。

盒子的生成

盒子的生成是CSS可视化格式模型的一部分,前面说CSS可视化格式模型为文档元素生成盒子,这些盒子是不同类型的,这取决于CSS的display属性值。可视化格式模型对不同类型的盒子采取不同的行为。

Block-level elements and block boxes(块级元素和块框)

当一个元素CSS的display的属性值是:block,list-item或者table时,这个元素被叫作块级元素。一个块级元素通常作为一个块被可视化格式,一般会垂直放置。

每个块级盒子会块级格式化上下文(BFC)。每个块级元素会至少生成一个块级盒子,这个盒子被叫做主块级盒子。一些元素,比如list-item元素会生成比较多的盒子,但是都只有一个主块级盒子。

主块级盒子包含子代生成的盒子和它自己生成的内容,它与定位的方案有关。

一个块级盒子可能也是一个块容器框。一个块容器框是一个只有块级盒子或只有行级盒子的盒子。值得注意的的是块级盒子和块容器框的概念是不相关的。块级盒子描述的是盒子和他的父以及他的兄弟之间的行为方式,而块容器框描述的是它的子代的相互作用的方式。一些块级盒子,比如table,不是块容器框。并且一些块容器框,比如一些不可替代的行内块以及一些不可替代的table元素,也不是块级盒子。既是块级盒子又是快容器框的盒子叫做块框( block boxes)。

Anonymous block boxes(块匿名框)

某些情况下,可视化格式模型需要添加额外的盒子。因为CSS选择器不能为这类盒子添加样式或则命名,故他们被叫做匿名框。

块容器框只能包含块级盒子或者只能包含行级盒子。但是通常文档会包含两类的盒子。在这种情况下,会创建一个块级匿名框包含行级盒子。

如下代码:

<div>Some inline text <p>followed by a paragraph</p> followed by more inline text.</div>

两个块级匿名框将被创建,一个用于包含Some inline text,一个用于包含followed by more inline text,分别位于<p>的前后.显示结果会如下:

Some inline text
followed by a paragraph
followed by more inline text.

上面的匿名框不像P标签一样,他的样式是不能控制的,只能是使用继承样式或则默认样式,不能像p一样自定义自己的样式,比如p可以设置自己的background-color,而两个匿名的只能使用div的background-color。

另一个会导致匿名块框的创建是在一个行框中包含一个或多个块框的时候。这种情况下,行框被分成两个行框,一个在块框之前,一个在他之后。所有行框再被一个匿名块框包含。最终,这个块框有两个匿名的块框兄弟,这两个匿名的块框包含着行框。

例如:

<span>this is a inline<p>this is a block</p>this is a inline</span>

上面的首先会变成:

<span>this is a inline</span><p>this is a block</p><span>this is a inline</span>

最后给span包裹一个匿名的块框。

Inline-level elements and inline boxes(行级元素和行框)

当一个元素CSS的display的属性值是:inline,inline-block或则inline-table,这个元素被叫作行级元素,通常它不是构成内容的块,但是和其他行级内容被分布在一行中。典型的有多种格式的一行内容,比如emphasis 和 images,被定义为行级元素。

行级元素会生成行级盒子。行框是既是行级盒子又是盒子的内容参与内联格式化上下文IFC的盒子。比如对于所有不可替代的display值为inline的元素。行级盒子中他们的内容不是用IFC格式化的那些盒子被叫做atomic inline-level boxes(自动行级盒子)。这些盒子,由可替代的行级元素生成或则具有display属性值为inline-block或inline-table的元素,如果可以用行框的时候,他们不会被分为几个盒子。

行级盒子和自动行级盒子的区别:

<style>
  span {
    display:inline; /* default value*/
  }
</style>
<div style="width:20em;">
   The text in the span <span>can be split in several
   lines as it</span> is an inline box.
</div>

上面width的限制,他可能会如下显示:
The text in the span can be split into
several lines as it is an inline box.

<style>
  span {
    display:inline-block;
  }
</style>
<div style="width:20em;">
   The text in the span <span>cannot be split in several
   lines as it</span> is an inline-block box.
</div>

而上面这个他可能会这样显示:

The text in the span 
cannot be split into several lines as it is an 
inline-block box.

Anonymous inline boxes(匿名行级框)

对于块框,这里有些情况会被CSS引擎自动创建行框。这些行框也是匿名的,他们不能被命名,他们是通过继承样式或则一些默认的样式设置自己的样式。

当一个行级框被创建的一个比较多的情况是:在一个块框中发现一些孩子且是文本元素且被IFC格式化。在这种情况下,这个文本元素被包含在一个大的行匿名框中。元素内的空白由CSS中的white-space属性处理,使其不会为一个空白建立匿名行级盒子。

如下会建立一个匿名的行级盒子:

<div>Some inline text followed by a paragraph followed by more inline text.Some inline text followed by a paragraph followed by more inline text.Some inline text followed by a paragraph followed by more inline text.Some inline text followed by a paragraph followed by more inline text.</div>

这里的div的display被设置为inline;

其他类型的盒子(line boxes和Run-in boxes)

line boxes由IFC生成并且代表文本的一行,在块框里,一个line boxes会排成一行。当有float的时候,行的左边在float为left的最右边,行的右边在float为right的最左边。

这些盒子的使用,一般情况都不会有什么困扰。

Run-in Boxes被display定义为run-in的元素会生成这个盒子,它可以是块框也可能是内联框,这取决于紧跟着他的盒子的类型。他们可以用来创建标题一个位于段落前面的小标题。值得注意的是,他它在CSS2.1中被删除,CSS3中还是实验阶段,不应该用在实际的代码中。

盒子的布局

一旦盒子被生成且被渲染,CSS引擎开始对其进行定位和布局,他使用了下面的这几条规则进行:
1. 普通流中,盒子是一个接一个有序的;
2. 在使用float定位的盒子中,这个盒子会在他所处的包含他的盒子中向左或向右重新定位;
3. 在absolute绝对定位中,这个绝对定位相对于的那个元素会创建一个坐标系统用于这个元素的定位,这个绝对定位的元素可能会覆盖在其他的元素上面;

Nomal flow(普通流)

在普通流中,盒子是被一个接一个的放置,在BFC区域里,盒子会垂直分布;在IFC中,盒子会水平分布。当position的属性值是static或relative,float的值为none时,这个元素盒子是在普通流中的。

float(浮动)

在浮动定位系统中,有一个特殊的用于指向当前这行的开始或结尾的盒子,被叫做(floating boxes or simply floats)。如果float设置成left,浮动将被指向这行开始的地方,right时,浮动将被指向这行的末尾。

Absolute positioning(绝对定位)

在绝对定位系统中,这个盒子被完全移除普通流中,并且不会和这个流中的盒子相互影响。他们的位置依赖于他们相对于的那个容器盒子的坐标系统,通过top,buttom,left和right设置自己的坐标。

一个元素会绝对定位,则他的dispaly属性值为absolute或fixed。

具有fixed值得元素,他的容器盒子是视图窗口。他的坐标都是相对于整个视图窗口,滑动条的滑动不会使其坐标发生变化。

盒子的不同类型具有不同的内部布局规则

前面说到,不同类型的盒子会参与不同的可视化格式模型(决定如何渲染文档的容器)。下面讲讲BFC(块级格式化上下文)和IFC(内联格式化上下文)。

Block Formating Context(BFC)

他是一个独立的区域,只有block-level box参与,他规定内部的block-level box如何布局,并且与这个区域外部不相干。

下面这些情况会生成一个BFC区域:
1. 根元素;
2. float属性值不为none;
3. position属性值为absolute或则fixed;
4. display属性值为inline-block,table-cell,table-caption,flex,inline-flex;
5. overflow属性值不为visible;

BFC规则:
1. 内部的box会垂直方向上一个接一个的放置;
2. box垂直方向上的距离由margin决定。
3. 每个元素的margin box的左边,与包含快的左边相接触,即使存在浮动;
4. BFC区域不会与float重叠;
5. BFC是页面上的一个隔离的独立的容器,容器内的子元素不会影响到外面的元素;
6. 计算BFC的高度时,浮动元素也参与计算。

BFC包含他创建的每个元素,但不包含创建的元素的子代元素,那些子代元素由一个新的BFC创建子代元素。

BFC在定位和浮动中应用比较重要,因为这个操作将只会影响到同一个BFC区域,不会是其他的区域受到影响。比如清除浮动不会影响在其他BFC中的布局,并且清除浮动只是在同一个BFC中进行操作。

Inline Formating Context(内联格式化上下文)

并不是行级元素就是参与IFC,前面可以看出display属性值为inline-block的元素会生成行级盒子但是他会参与BFC。行框会参与IFC。对于IFC,行高由行内元素最高的实际高度计算而来。

下面是IFC的一些规则应用:
1. 行框一般紧贴整个IFC,但是会因为float而被扰乱。float元素会位于IFC和行框之间。
2. 水平居中:当要一个快水平居中时,设置inline-block会在外层产生一个IFC(注意是在外层产生的,不是元素本身呢个),通过text-align可实现水平居中;
3. 垂直居中:创建一个IFC,用其中一个元素撑开父元素的高度,然后设置vertical-align:middle,其他的即可垂直显示。

div水平居中:

<style>
    body{
        text-align: center;
    }
    #mzz{
        width:400px;
        height: 400px;
        display: inline-block;
        border: 1px solid #ff0000;
    }
</style>
//上面的text-align和display缺一不可
<body>
    <div id="mzz">
    </div>
</body>

DOM节点渲染详解--盒子的生成到布局过程

标签:

原文地址:http://blog.csdn.net/mzzzzq/article/details/51194049

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!