CSS 视觉格式化模型

155 阅读9分钟

写在前面

我们知道在 CSS 中,布局的基本单位是盒(矩形),然后是由盒子组成的某块区域。

不同类型的盒(指行盒、块盒、行块盒、可替换元素)有其本身的性质,请看《盒模型》

网页中还有三种布局方式:常规流浮动定位

加上三种布局方式后,就可进一步把盒划分为常规流块盒常规流行盒常规流行块盒浮动盒定位盒

什么是视觉格式化模型?

官方是这样解释的:视觉格式化模型是用来处理和在视觉媒体上显示文档时使用的计算规则。

我是这样理解的:官方对每种盒子的性质做了规定,也对盒子组成的某些区域(上下文)及其内部盒子的排列方式做了规定,这些规定构成了视觉格式化模型

一句话,视觉格式化模型是一种布局规则,针对页面中的盒子以及某块区域。

包含块

在详细介绍视觉格式化模型之前,先来理解包含块概念,它的含义如下:

  1. 每个盒子都有它的包含块,包含块决定了盒子的活动范围。
  2. 但是盒子并不由包含块所限制,当盒子的布局跑到包含块的外面时称为溢出。
  3. 可以把包含块看作盒子偏移时的相对坐标,即盒子的偏移量是相对于其包含块进行的。
  4. 绝大部分情况下,盒子的包含块为其父元素的内容盒;绝对定位元素的包含块是其祖先元素的第一个定位元素的填充盒,若找不到则它的包含块为整个网页(初始化包含块);固定定位的包含块为视口(浏览器的可视窗口)。

关于盒子性质

我们可以把盒子性质分为盒子尺寸盒子排列两部分来看。

讨论盒子尺寸时,重点是块盒,除了《盒模型》给出的块盒性质外,还有两种比较特殊的取值情况:auto(水平方向与垂直方向)和百分比其中auto只会在width、height和margin属性上设置

讨论盒子排列时,重点是盒子的排列特性以及其常见的使用场景。

接下来,逐一来看一下各类盒子的性质吧!

常规流块盒性质

盒子尺寸

水平方向上的auto

  • 水平方向上的auto含义是将包含块剩余空间吸收掉
  • 当content、padding、border、margin有固定值时,先减去固定值,再去吸收剩余宽度(width的吸收能力大于magin)
  • width默认值为auto,会默认吸收剩余宽度,margin默认值是0,设置了margin:auto才会开启其吸收能力

垂直方向上的auto

  • height:auto表示适应内容的高度,margin:auto表示0。

百分比取值

  • width、padding、margin的百分比取值相对于包含块的宽度(即使padding-top也是相对于宽度取值)。
  • height的百分比取值要分情况:如果其包含块的高度取决于子元素的高度,设置百分比无效;如果其包含块的高度不取决于子元素的高度,百分比相对于包含块的高度。

盒子排列

  1. 上下外边距叠加:两个盒子的上下外边距毗邻(垂直方向上,两个盒子的外边距之间没有空白,这两个盒子就是毗邻的,可以是父子元素或者兄弟元素),会进行合并,两个外边距取最大值。

关于常规流行盒与行块盒的性质,请看《盒模型》

浮动盒性质

元素浮动后,必定为块盒,同时会脱离文档流,但它跟文档流还有点联系。

盒子尺寸

水平方向上的auto

  • width:auto表示适应内容宽度;margin:auto表示0。

垂直方向上的auto

  • height:auto表示适应内容的高度;margin:auto表示0。

百分比取值

  • 和常规流块盒一样。

盒子排列

  1. 左浮动盒子靠上靠左排列。
  2. 右浮动盒子靠上靠右排列。
  3. 浮动盒子的顶边不得高于上一个盒子的顶边。
  4. 若剩余空间无法放下浮动的盒子,则该盒子向下移动,直到具备足够的空间能容纳盒子,然后再向左或向右移动。
  5. 不会发生外边距叠加:因为浮动元素会创建一个BFC,此性质属于BFC的规定。
  6. 与常规流盒子的交互:浮动盒子在包含块中排列时,会避开常规流块盒,但不会避开常规流行盒;常规流块盒在排列时,会无视浮动盒子;常规流行盒在排列时,会避开浮动盒子。
  7. 父元素高度坍塌:因为常规流盒子的自动高度在计算时,不会考虑浮动盒子(因为浮动盒子脱离了常规流),解决方式是清除浮动(不展开讨论)。

定位盒性质

元素绝对定位或固定定位后(排除相对定位,它不会改变盒子性质),必定为块盒,同时它们会完全脱离文档流。

定位盒又分为相对定位盒、绝对定位盒、固定定位盒,它们的盒子尺寸、盒子性质基本和常规流块盒、浮动盒保持一致,这里就不做详细介绍,只是简单的罗列一下。

相对定位盒

  • 盒子尺寸:和常规流块盒一样。
  • 盒子排列:只是让元素在原来位置上进行偏移,但盒子的偏移不会对其他盒子造成任何影响,通常用来为绝对定位的元素提供包含块。

绝对定位盒

  • 盒子尺寸:和浮动盒一样。
  • 盒子排列:相对于包含块进行偏移。

固定定位盒

都和绝对定位盒保持一样。

对以上的内容,总结一下,对于各类盒子在水平或者垂直方向上的width、height、margin属性,它们的auto值的含义(重点是图中标绿的区域,它们会在很多经典的布局上面使用到):

常规流块盒和相对定位盒是一样的,而浮动盒、绝对定位盒和固定定位盒是一样的。

auto含义.png

关于盒子规则的部分到这里为止,接下来再来看一下区域的规则吧!

关于上下文规则

在css中有些特殊的区域:块级格式化上下文行级格式化上下文层叠上下文等。当然,CSS3也新增了网格布局格式化上下文自适应格式化上下文,但本文并不涉及。

块级格式化上下文(BFC)

它是一块独立的渲染区域,它规定了在该区域中,常规流块盒的布局,不同的BFC区域,它们进行渲染时互不干扰。

BFC规则

  1. 创建BFC的元素,它的自动高度需要计算浮动元素
  2. 创建BFC的元素,它的边框盒不会与浮动元素重叠
  3. 创建BFC的元素,不会和它的子元素进行外边距合并

哪些元素会在其内部创建BFC

  1. 根元素
  2. 浮动或定位元素
  3. overflow不等于visible的元素
  4. display值为inline-block、table-caption、table-cell的元素

行级格式化上下文(IFC)

它是一个独立的区域(行盒),其中的行内元素按照一定的规则排列,可以通过设置IFC的属性来控制行内元素的排列方式。

IFC规则

  1. IFC中的元素按照从左到右的顺序排列,每个元素占据一定的宽度
  2. IFC中的元素可以通过设置vertical-align属性来控制垂直方向上的对齐方式
  3. IFC中的元素可以通过设置text-align属性来控制水平方向上的对齐方式
  4. IFC中的元素可以通过设置line-height属性来控制行高,从而影响行内元素的垂直对齐方式

行盒中的一些概念

  1. 顶线:内容顶部线
  2. 中线:底线和顶线平均线
  3. 基线:字母x的下端沿
  4. 底线:内容底部线
  5. 内容区:内容底线和顶线包裹区域
  6. 行内框:浏览器默认渲染出来的,高度等于行高,一个行内框可以被分割到多行中
  7. 行框:行框的大小将足以包含该行中所有的行内框,只有一行时其高度等于本行所有元素中行高最大的值
  8. 行高:单行时它包括了行框高度和上下间距高度,多行时指的是每行基线间的距离,它的值可以设置
  9. 行距:上文本行基线与下文本行顶线之间距离

在下图中,紫色区域是行内框,黑色区域是行框。

行内框盒行框.png

层叠上下文

它也是一块区域,由某个元素创建,它规定了该区域中的内容在z轴上排列的先后顺序。

同一个层叠上下文中的元素在z轴上的排列顺序(由下自上)

  1. 创建堆叠上下文的元素的背景和边框
  2. 负z-index
  3. 常规流非定位的块盒
  4. 非定位的浮动盒子
  5. 常规流非定位行盒
  6. 任何z-index:auto的定位子元素,以及z-index:0的层叠上下文
  7. 正z-index

哪些元素会创建层叠上下文

  1. 根元素(html)
  2. 设置了z-index数值的定位元素

总结

CSS 中,盒模型与视觉格式化模型都是非常重要的概念,而这两者的知识经常混在一起,所以最好是区分开来学习,然后结合起来使用!

CSS 视觉格式化模型中,很多的概念都有着丰富的内涵,只有在理解这些概念的基础上,还要多加实践,才能更好的掌握它们!

CSS 极其复杂,除了语义方面有丰富的概念外,其语法层面的 API 也非常多,需要花更多的时间来学习和实践!

祝大家都成为 CSS 大神!