二十、CSS视觉格式化模型

113 阅读4分钟

前言

CSS 视觉格式化模型(visual formatting model),是用来处理和在视觉媒体上显示文档时使用的计算规则。该模型是 CSS 的基础概念之一。

视觉格式化模型会根据 CSS 盒子模型将文档中的元素转换为一个个盒子,每个盒子的布局由以下因素决定:

  • 盒子的尺寸:精确指定、由约束条件指定或没有指定
  • 盒子的类型:行内盒子(inline)、行内级盒子(inline-level)、原子行内级盒子(atomic inline-level)、块盒子(block)
  • 定位方案: 普通流定位、浮动定位或绝对定位。
  • 文档树中的其他元素:即当前盒子的子元素或兄弟元素。
  • 视口尺寸与位置
  • 所包含的图片的尺寸
  • 其他的某些外部因素

盒子的渲染会根据自己的包含块(上一篇文章)来渲染盒子,每个元素都有自己的包含块,元素会根据包含块来渲染盒子的边界。当超过边界的时候称为溢出(overflow)每个块元素都会至少生成一个块级盒子且会参与BFC的创建。有一些元素,比如列表项会生成额外的盒子来放置项目符号,而那些会生成列表项的元素可能会生成更多的盒子。不过,多数元素只生成一个主块级盒子。

匿名块盒

  1. 在某些情况下进行视觉格式化时,需要添加一些增补性的盒子,这些盒子不能用 CSS 选择符选中,因此称为匿名盒子(anonymous boxes)
  2. CSS 选择器不能作用于匿名盒子 (anonymous boxes),所以它不能被样式表赋予样式。也就是说,此时所有可继承的 CSS 属性值都为 inherit ,而所有不可继承的 CSS 属性值都为 initial

举个例子

块包含盒子可能只包含行内级盒子,也可能只包含块级盒子,但通常的文档都会同时包含两者,在这种情况下,就会在相邻的行内级盒子外创建匿名块盒子。

<html lang="zn-CH">  
<head>  
<meta charset="UTF-8">  
<title>Rock学前端</title>  
<style>  
.flex {  
    display: flex;  
}  
  
.flex > * {  
    background-color: rebeccapurple;  
    color: white;  
}  
</style>  
</head>  
<body>  
<div class="container">  
<div class="flex">  
    I am wrapped in an anonymous box  
    <p>I am in the paragraph</p>  
    I am wrapped in an anonymous box.  
</div>  
</div>  
</body>  
</html>

效果:

image.png

解释:p 的前面和后面的文本都生成了匿名块盒。且不能被CSS 选中。所以文字并没有被选中,p下沉的原因是p默认样式由16px的margin。

定位规则

1. 普通流 :

当 CSS 的 position 属性为 static 或 relative,并且 float为 none 时,其布局方式为普通流。在普通流中,盒子会依次放置。在块格式化上下文中,盒子在垂直方向依次排列;而在行内格式化上下文中,盒子则水平排列。这也是我们常说的块级元素垂直排列且独占一行,行级元素水平排列的原因。

普通流又分为两种情况:position:static;position:relative;

  1. position:static;`:此时每个盒子根据普通流所计算出的确切位置来定位。
  2. 当 position 为 relative 时为相对定位,此时每个盒子还会根据 topbottomleft 和 right 属性的值在其原本所在的位置上产生指定大小的偏移。

2. 浮动:

  • 在浮动定位中,浮动盒子会浮动到当前行的开始或尾部位置。这会导致普通流中的文本及其他内容会“流”到浮动盒子的边缘处,除非元素通过一些方式清除浮动带来的影响。
  • 一个盒子的 float值不为 none,并且其position 为 static 或 relative 时,该盒子为浮动定位。如果将 float 设置为 left,浮动盒子会定位到当前行盒子的开始位置(左侧),如果设置为 right,浮动盒子会定位到当前行盒子的尾部位置(右侧)。不管是左浮动还是右浮动,行盒子都会伸缩以适应浮动盒子的大小。

清除浮动带来的影响:

.clearFix::after{
    content:"";
    display:block;
    clear:both;
}

3.绝对定位

在绝对定位中,盒子会完全从当前流中移除,并且不会再与其有任何联系(译注:此处仅指定位和位置计算,而绝对定位的元素在文档树中仍然与其他元素有父子或兄弟等关系),其位置会使用 topbottomleft 和 right 相对其包含块进行计算。

如果元素的 position为 absolute 或 fixed,该元素为绝对定位。

4.固定定位

对固定位置的元素来说,其包含块为整个视口,该元素相对视口进行绝对定位,因此滚动时元素的位置并不会改变。