css-2.1布局模型理解

前言

读了css2.1的Visual formatting model,结果搜索资料。把以前很多想不通的事情搞明白了。特记录于此,防止自己以后忘记。
本章主要讲了css2.1版本中布局的模型,通俗点说就是css如何控制html标签,让他们按照css定好的规矩进行布局,渲染。还有一章detail在下一个章节。读懂css的布局模型,先要搞懂几个概念。

布局方式

在css中,布局一共有三条规则。
1、Normal Flow(经常翻译成标准流、文档流、常规流等等)。

1
2
Normal flow. In CSS 2.1, normal flow includes block formatting of block-level boxes, inline formatting of inline-level boxes, and relative positioning of block-level and inline-level boxes.
这句话的意思是在标准流这种规则下,包含了块级盒子的按块布局,行内盒子的按行内布局还有俩种盒子的相对定位布局。

2、Floats: 浮动

1
2
In the float model, a box is first laid out according to the normal flow, then taken out of the flow and shifted to the left or right as far as possible. Content may flow along the side of a float.
这句话的意思是在浮动布局这种规则下面,盒子先按照第一种布局方式进行布局,然后尽可能的向左边或者右边贴近。

所以有人经常说float会导致盒子脱离标准流,是一种错误的说法。
3、Absolute positioning:绝对定位

1
2
In the absolute positioning model, a box is removed from the normal flow entirely (it has no impact on later siblings) and assigned a position with respect to a containing block.
这句话的意思是说盒子,在这种规则下面,会完全脱离标准流。

触发了Absolute positioning才会脱离标准流

可能直接翻译比较难理解。
总得来说,在前端领域。html提供了标签和属性。html其中的style属性是留给css的。css可以通过style属性来控制标签的样式。css把标签会定义为一种类似“盒子”的模型,称为box model,判断自己的文本,字体,背景等等属性来渲染自己,最后这些box会判断自己属于处于哪种规则下面,就按照哪种规则进行布局,排列。形成网页,呈现出来。规则就是上面的的三种规则,之后会详细解释什么情况下,触发哪种规则。

如何判断盒子按照哪种布局模式来布局

各位都知道与定位系统有关的CSS属性position:static|relative|absolute|fixedfloat:none|left|right,其中position的默认值是static,而float的默认值为none。而position:static|relative均属于Normal flow。
默认情况下,各个盒子就是按照Normal Flow规则进行布局。如果某个盒子设置了float的值为left/right,那么盒子就按照floats规则进行布局。如果某个盒子设置了position的值为absolute或者fixed的时候,那么这个盒子就会按照第三种的absolute positioning的规则进行布局。
那么问题来了?如果一个盒子的属性既设置了float属性为left,同时又设置了position的值为fixed,那么盒子会选择哪种规则呢?经过我在chrome里面测试,它会选择position的属性,然后float属性自动转换为none。测试代码如下:

如何判断盒子按照哪种布局模式来布局,大致如下:

一些概念

Box: CSS布局的基本单位

1
2
3
4
5
6
7
Box 是 CSS 布局的对象和基本单位, 直观点来说,就是一个页面是由很多个 Box 组成的。元素的类型和 display 属性,决定了这个 Box 的类型。 不同类型的 Box, 会参与不同的 Formatting Context(一个决定如何渲染文档的容器),因此Box内的元素会以不同的方式渲染。让我们看看有哪些盒子:

block-level box:display 属性为 block, list-item, table 的元素,会生成 block-level box。并且参与 block fomatting context(BFC);

inline-level box:display 属性为 inline, inline-block, inline-table 的元素,会生成 inline-level box。并且参与 inline formatting context(IFC);

run-in box: css3 中才有, 这儿先不讲了。

Formatting context

1
2
3
Formatting context 是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。最常见的 Formatting context 有 Block fomatting context (简称BFC)和 Inline formatting context (简称IFC)。

CSS2.1 中只有 BFC 和 IFC, CSS3 中还增加了 GFC 和 FFC。

Normal Flow布局模式详解

当我们确定某个元素是确定在Normal Flow模式规则下面进行布局的时候,这时候,在这个大规则下面还要区分盒子是在IFC还是BFC的里面。当我们采用绝对定位或浮动定位时,就没有必要再讨论IFC和BFC了。

BFC布局规则

  • 内部的Box会在垂直方向,一个接一个地放置。
  • Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠(margin塌陷)
  • 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
  • BFC的区域不会与float box重叠。
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
  • 计算BFC的高度时,浮动元素也参与计算
    这就是平时我们说的块级盒子在Normal Flow规则下,同时也处于BFC的容器里面的时候,会参与的布局规则。也是我们最常见的规则。

    哪些元素会生成BFC?

  • 根元素
  • float属性不为none
  • position为absolute或fixed
  • display为inline-block, table-cell, table-caption, flex, inline-flex
  • overflow不为visible

有人这时候就会迷糊了,float和定位会产生BFC,BFC又是Normal Flow规则下面的一个规则,让人头晕的很。这时候就要引入新的概念了——containing block。翻译成“容器块” 。一个元素如何定位,首先要看自己处于上面三种布局的哪种模式下,确定之后。就要看自己的容器块是什么了。类似下面这样判断:

类比的话,就是每个元素(盒子)先判断自己属于哪个国家,就要遵守哪个国家的法律。之后就要判断自己在这个国家的那一个省市,根据省市的具体法律法规进行谋生。

Floats 布局模式详解

这感觉没啥好解释的。略过。
有一点就是当行内元素设置float的时候,display的属性值会从inline自动转化为block

absolute positioning布局模式详解

当一个元素的position属性值为absolute或者fixed的时候,进行这种布局规则。同时这个元素的float属性值自动转换为none,display的属性值自动转换为block。

总结

若有纰漏,请各位指正

参考

https://www.w3.org/TR/CSS2/visuren.html#positioning-scheme
https://www.cnblogs.com/fsjohnhuang/p/5364580.html
http://www.cnblogs.com/fsjohnhuang/p/5259121.html
http://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.html