CSS-vitual formatting model

在视觉格式化模型中,文档树(dom)中的每一个元素根据盒子模型(box model)产生0个或多个盒子(box)。而这些盒子的布局由以下因素决定:

  • 盒子尺寸和类型
  • 位置调度(normal,float,absolute)
  • dom中元素之间的关系
  • 外部信息(ex.viewport大小)

    视觉格式化模型并没有指定格式化的所有方面。

9.1.1 视窗(viewport)

连续媒体的用户代理通常向用户提供一个查看文档的视窗(viewport,在屏幕上的一个窗口或其他可视区域)。用户代理可能会在视窗大小变化的时候改变文档的布局。
当视窗小于文档上被渲染的canvas区域的时候,用户代理应该提供一个可滚动的机制。通常每个canvas存在一个视窗,但用户代理可能渲染超过一个canvas(ex.给同一个文档提供不同的视图)

9.1.2容器块(containing blocks)

在css2.1中,很多的盒子大小和位置的计算是和被称为“容器块(containing blocks)”的矩形盒子的边联系在一起的。通常,生成盒子表现为包含为后代盒子的块。我们把这称为一个盒子为后代建立容器块。
我们说“一个盒子的容器块”指的是这个盒子的生存环境,而不是这个盒子产生的。
每一个盒子的位置都是参照它的容器块,但并不限于这个容器块,有可能会溢出。
文档树的根产生一个为随后的布局服务的初始容器块的盒子,初始容器块的宽度可能被根元素的“width”属性所规定,如果这个属性被定义为“auto”,user agent 提供初始宽度。高度同样如此,不过如果同样为“auto”,将变为可容纳文档内容的高度。初始容器块不能被定位或浮动。

控制盒子生成

下面的内容描述了css2中能够产生的盒子的类型。盒子的类型在一定程度上影响着它在视觉格式模型中的行为。而“display”属性规定了盒子的类型。

块级元素和块盒子

块级元素指的是那些源文档中通常被格式化为块(block)的元素。“display”的一些纸会使元素变为块级(block-level):”block”,”list-item”,”compact”,”run-in”,”table”。
块级元素产生只包含块级盒子的主要盒子。主要盒子为后代盒子建立容器块并产生内容而且参与到定位方案中。主要盒子参与块级格式化上下文。
一些块级元素在主盒子外产生额外的盒子:“list-item”和那些有”markers” 的元素。那些额外的盒子的定位于主盒子相关联。

  • 匿名块级盒子
    在下述文档中:
<div>
  some text
  <p>more text</p>
</div>

div元素呈现出包含块级元素和行内元素。为了更方便的去定义格式化,我们假设有一个匿名的盒子包含着“some text”。anonynousBox
也就是说:如果一个 块级盒子的内部有另外一个块级盒子,我们会通过封装所有行级盒子为匿名的块级盒子去强制它只含有块级的盒子。
匿名盒子的属性会从封闭的非匿名盒子继承下来,不可继承的属性有初始化的值。

行级元素与行内盒子

行级元素指的是那些源文档中不会形成新的块级内容的元素;内容被分配在行内部。元素的“display”属性被赋值为以下几个的时候会使得元素变成行内元素:“inline”,“inline-table”,”compact”,”run-in”;行级元素产生行盒子;
行盒子参与以下几个格式化上下文:

  • 在块级盒子中,行盒子参与到“行格式化上下文”中
  • compact 的行盒子被定位到块盒子的margin中;
  • marker盒子也被定位在块盒子外面

    匿名行盒子

    基本概念和性质与匿名块盒子类似;
    在格式化table中会有很多类型的匿名盒子出现。

compact盒子

一个compact盒子表现如下:
- 如果一个块盒子出现在compact盒子之后,这个compact盒子会表现得像一个 one-line inline box。这个导致的盒子宽度相比于这个块盒子的margin的一边。是左侧还是右侧的margin取决于为compact元素和块元素的产生容器块的元素的direction属性。如果行盒子的宽度小于或等于margin,这个行盒子会被定位在margin,下面将细述。
- 否则,compact会变成一个块盒子

compact盒子将会按照下述给出在margin中的位置:这是块盒子的第一个line-box的外部,但是影响到了line-box高度的计算。compact 盒子的vertical-align属性决定了compact盒子关联的line-box的水平位置。compact盒子的水平位置通常位于块盒子的margin位置。

display 属性

“display”

  • value: inline | block | list-item | run-in | compact | marker | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | none | inherit
  • initial:inline
  • applies to:all elements
  • inherited:No
  • percentage:N/A
  • media:all

    这个属性的一些值分别代表下述含义:

  • block:使得元素产生主要块盒子
    -inline:使得元素产生一个或者多个行盒子

  • list-item:使得元素产生一个主要块盒子和一个list-item行盒子
  • marker:声明一个盒子产生的前面或者后面的内容为marker;只能用在块级元素的“:before”或者“:after”伪元素上。换句话说,这个属性被解读为”inline“
  • none:使得元素在格式化结构中不产生盒子;后代元素同样不产生。
  • table(table-cell,table-row…):使得元素表象得像表格元素

要注意的是虽然”display“属性的初始值是”inline”,用户代理的默认样式可能会覆盖这个值。

定位方案

在css2中,一个盒子会被下述定位方案所编排:

  • 正常流(normal flow):在css2中,正常流包括块盒子的块级格式化,行盒子的行格式化,块盒子或者行盒子的相对定位,compact和run-in盒子的定位。
  • 浮动(floats):在浮动布局中,盒子首先根据正常流编排,然后从流里拿出来放到尽可能左或者右边。
  • 绝对定位:在绝对定位模型中,盒子被完全的从正常流里拿出来然后被定位在容器块的相对位置。

    选择一个定位方案:”position“属性

    css2中的定位算法属性”float“和”position“被用来计算盒子的位置。

    ”position“

  • Value: static | relative | absolute | fixed | inherit

  • Initial: static
  • Applies to: all elements, but not to generated content
  • Inherited: no
  • Percentages: N/A
  • Media: visual

这些值分别有下述意义:

  • static:正常流盒子,根据正常流定位,top和left属性不起作用
  • relative:根据正常流定位;根据left和top属性相对于正常流位置的偏移;之后的元素定位则把该元素当作没有偏移
  • absolute:位置根据top,left,right,bottom决定;偏移相对于容器块。决定定位的盒子会被从正常流文档中拿出来。这意味着他们不会对后面的兄弟元素的布局产生影响。同样的,即使绝对定位盒子拥有margin,但是不会跟其他margin冲突。
  • fixed:根据”绝对定位模型“计算位置。但此外,盒子是关于一些参考物。在连续媒体的例子中,盒子被关联定位于视窗(viewport)。在paged媒体的例子中,盒子被定位关联于page,即使page是通过视窗看到的。作者可能希望能够根据媒体确定fixed定位。实际上,可以通过媒体查询来分别定位@media (screen/print){};

    盒子偏移:top,right,bottom,left

    如果一个元素的position属性是static以外的,我们就说这个元素是可定位的。可以被定位的元素产生可以被定位的盒子,布局规则通过下述四个属性:

  • top:

Value: | | auto | inherit
Initial: auto
Applies to: positioned elements
Inherited: no
Percentages: refer to height of containing block
Media: visual
这个属性决定了盒子内容区的上边与容器块的上边有多大的距离。
- right:

Value: | | auto | inherit
Initial: auto
Applies to: positioned elements
Inherited: no
Percentages: refer to width of containing block
Media: visual
这个属性决定了盒子内容区的右边与容器块的右边有多大的距离。
- bottom
Value: | | auto | inherit
Initial: auto
Applies to: positioned elements
Inherited: no
Percentages: refer to height of containing block
Media: visual

这个属性决定了盒子内容区的底边与容器块的底边有多大的距离。
- left

Value: | | auto | inherit
Initial: auto
Applies to: positioned elements
Inherited: no
Percentages: refer to width of containing block
Media: visual
这个属性决定了盒子内容区的左边与容器块的左边有多大的距离。

四个属性的值的意义是:
length : 偏移距离参考边缘的固定距离。
percentage : 偏移容器块的百分比宽度或者高度;如果高度没有定义,则被解释为auto
auto:这个值的影响取决于与之相关的属性同样拥有auto值。

对于绝对定位的盒子,偏移取决于盒子的容器块。对于相对定位的盒子,偏移取决于盒子本身的外边框。

正常流

盒子在正常流中属于一个可能是块级或者行级的格式化上下文,但不能同属二者。块级盒子参与到块级格式化上下文中,行级盒子参与到行级格式化上下文中。

块级格式化上下文

在块级格式化上下文中,盒子一个垂直的接着一个分布,从容器块的顶部开始。两个相邻盒子的垂直距离取决于margin属性。在块级格式化上下文中相邻盒子的垂直margin会发生崩塌。
在块级格式化上下文中,每个盒子的左外边都碰到容器块的左边。在浮动模型中也是如此。

行级格式化上下文

在一个行级格式化上下文中,盒子从容器块的顶部开始一个接着一个水平地排列。这些盒子都遵循水平margin,border,padding。这些盒子会以不同的方式被垂直的对齐:根据底部或者顶部,或者它们内部文本的基线对齐。由于包含这些盒子的矩形区域像线一样因此被称为line-box。

line-box的宽度取决于容器块。至于line-box的高度则是由在行高计算区域的规则决定的。line-box对于其包含的盒子来说通常是足够高的。然而,也可能会比其中最高的盒子要高。当一个盒子的高度要比包含它的line-box高度要小的时候,这个盒子在line-box中的垂直对齐方式取决于“vertical-align”属性。当多个行内盒子不能垂直适应单个line-box的时候,他们会分布在多个垂直堆叠的line-box中。如此,一个断了就是一个垂直的line-box堆。line-box被堆叠起来的时候没有垂直间隙而且也不会覆盖彼此。
一般来说,行盒子的左边接触着它的容器块的左边,右边同样如此。然而,浮动盒子可能会出现在容器块和line-box的边之间。如此,即使在同一个行级格式化上下文的line-box拥有相同的宽度,如果它们可用的水平空间被浮动减少的话,他们实际的宽度也可能是变化的。在同一个块级格式化上下文的行盒子的高度是可能不一样的。
当行盒子的宽度小于包含这它们的行盒子时,它们在盒子中水平的分布取决于“text-align”属性。如果属性的值为“justify”,用户代理会规划好那些行盒子。
因为行内盒子不会超出行盒子的宽度,长行盒子被分割为几个盒子,这些盒子包含几个行盒子。当一个行内盒子被分割时,margin,border,padding都没有视觉上的影响。当分割出现在双向嵌入的时候,margin,padding,border可能不会被完整的定义。
在双向文本处理的时候,行内盒子也可能会在一个盒子中被分割成几个盒子。

相对定位

在一个盒子根据正常流被定位的时候,它可能会相对于原本的位置移动。这叫做相对定位。移动一个盒子对后面的盒子来说没有任何影响。这可能会导致盒子被覆盖。
相对定位的盒子保持它们的大小,包括break,和保留原本的位置。一个相对定位的盒子为正常流的子代产生一个新的容器块。
当一个元素的“position”属性被赋值为“relative”的时候产生一个相对定位盒子。偏移取决于“margin”,“left”,“right”,“bottom”这些属性。

Floats

浮动指的是一个盒子移动到当前行的左边或者右边。浮动最有意思的特性是内容沿着边沿移动。内容浮动到左浮动盒子的右边或者右浮动盒子的左边。接下来介绍的是浮动的位置和内容浮动;管理浮动行为的精确的规则。
一个浮动的盒子必需要有明确的宽度(通过“width”赋值或者在替换元件的情况下的固有宽度)。任何浮动盒子都会变成块盒子,然后浮动至左边或者右边直到它的外边碰到容器块的边或者其它浮动盒子的边。浮动盒子的顶部与当前行盒子的顶部对齐(或者前一个块盒子的底部,没有行盒子的时候)。如果当前行的垂直高度小于浮动盒子的高度,它会向下移动,一行一行的,直到有一行有足够的空间。
因为浮动元素不在文档流中,也就没有被定位的块级盒子在浮动元素的前面或者后面被创建,这样就会表现得像这个浮动元素并不存在。然而,被创建在于浮动元素相邻的行盒子会被缩短以留出足够的空间给浮动盒子。任何在浮动盒子前面的内容会被重新回流到除了浮动盒子以外的可用区域。
多个浮动元素可能是临近的,这个模型也适用于同一行中临近的浮动元素。
浮动盒子的margin永远不会与临近的盒子产生塌方。浮动的盒子会覆盖在正常流中的盒子。当一个行盒子被浮动元素覆盖的时候,行盒子的content,background,borders被渲染在浮动元素的前面。当一个块盒子被覆盖的时候,块盒子的background和borders会被渲染在浮动元素的后面,只有当盒子透明的时候才可见。但块盒子的内容会被渲染在浮动元素的前面。

“float”属性

‘float’
- Value: left | right | none | inherit
Initial: none
Applies to: all but positioned elements and generated content
Inherited: no
Percentages: N/A
Media: visual

浮动属性可能被设置到产生除了absolute定位的盒子的元素。

  • left:元素产生一个向左浮动的盒子。内容则从上开始向右流动;display属性会被忽略,除了none之外。
  • right:同left
  • none:盒子不浮动。

    管理浮动行为的规则:

  • 左浮动盒子的左外边可能不会碰到容器块的左外边,右边类似。

  • 如果当前盒子是左浮动的,而且在源文档也有更早的元素产生左浮动的盒子,如此对于每一个更早的浮动盒子,更早浮动盒子的右边成为后一个浮动盒子的左边,或者它的顶部要比前面盒子的底部更低。右浮动类似。
  • 左浮动盒子的右外边可能不是浮动到这个盒子的右边的右浮动盒子的左外边的右边。
  • -
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值