CSS规范 > 9 视觉格式化模型 Visual Formatting Model

视觉格式化模型 Visual Formatting Model

URL:http://www.w3.org/TR/CSS2/visuren.htmlcss

Translator: HaoyCn html

Date: 14th of Aug, 2015算法

本文并未所有翻译,译者在原文基础上稍有添加图示。如了解所有信息,请参看规范原版。我的水平有限,欢迎指正。app

9.1 视觉格式化模型介绍

本章和下章用于描述视觉格式化模型:用户代理 User Agent 如何在视觉媒体 Visual Media 下处理文档树 Document Tree 框架

视觉格式化模型中,文档树中的每个元素根据盒模型 Box Model 产生零个或多个盒。这些盒的布局由如下内容控制:ide

  1. 盒的尺寸和类型布局

  2. 定位体系 Positioning Scheme (常规流,浮动和绝对定位)字体

  3. 文档树中元素之间的关系动画

  4. 外部信息(如:视口大小,图片的固有尺寸等)this

本章及下章定义的属性适用于连续媒体和页面媒体 Paged Media 。然而,外边距属性的意义在页面媒体中有所不一样(详情见页面模型)。

视觉格式化模型没有指定格式化的全部方面(如,没有指定字符间距算法)。本规范没有覆盖到的格式化问题上,符合规范的用户代理也可能表现不一。

9.1.1 视口 The Viewport

在连续媒体 Continuous Media 上工做的用户代理通常会向用户提供一个视口(屏幕上的一个窗口或其它可视区域)来帮助用户访问文档。用户代理能够在调整视口大小的同时改变文档的布局(见初始包含块 Initial Containing Block )。

若是视口小于渲染文档的画布区域,用户代理应提供一个滚动机制。每一个画布最多有一个视口,但用户代理能够把文档渲染到多个画布上(即为相同文档提供不一样视图)。

9.1.2 包含块 Containing Blocks

CSS2.1中,许多盒的定位和大小都根据一个名为包含块 Containing Block 的矩形盒的边缘来计算。通常地,生成的盒会充当其后代盒的包含块;咱们称盒为其后代“建立”了包含块。说“盒的包含块”便是说“盒所处的包含块”,而不是盒所产生的包含块。

每一个盒会被赋予一个相对于其包含块的位置,但它不会被局限在其包含块内;它有可能溢出。

包含块的尺寸如何计算的细节将在下章讲述。

9.2 盒的生成 Controlling Box Generation

本节描述CSS2.1中可生成的盒类型。盒的类型会影响其在视觉格式化模型中的表现。下面描述的 display 属性用来指定盒的类型。

9.2.1 块级元素 Block-level Elements 和 块盒 Block Boxes

块级元素是源文档中会被视觉格式化为块状(例:段落)的元素。 display 属性的如下值会让一个元素成为块级元素: block list-item 以及 table

块级盒 Block-level Boxes 是参与块格式化上下文 Block Formatting Context 的盒。每一个块级元素生成一个主要的块级盒 Principal Block-level Box 来包含其后代盒和生成的内容,同时参与定位体系 Positioning Scheme 。某些块级元素还会在主要盒以外产生额外的盒: list-item 元素。这些额外的盒会相对于主要盒来摆放。

除了(下章要讲的)表格盒 Table Boxes ,和可替换元素( Replaced Elements ),一个块级盒同时也是一个块容器盒 Block Container Box ,一个块容器盒要么只包含块级盒,要么建立一个行内格式化上下文 Inline Formatting Context 并只包含行内级盒 Inline-level Boxes 。并不是全部的块容器盒都是块级盒:不可替换的行内块 Bon-replaced Inline Blocks 和不可替换的表格单元格 Non-replaced Table Cells 也是块容器但不是块级盒。是块级盒、同时也是块容器的盒称做块盒 Block Boxes

这三个术语,“块级盒”、“块容器盒”、“块盒”在乎义明确时可简称为“块”。

n8TjeCd.png

9.2.1.1 匿名块盒

在一个以下文档中:

<div>
   Some text
   <p>More text</p>
</div>

(假定 div p 都设置了 display: block ,) div 看起来彷佛同时包含了行内类型的内容和块类型的内容。为了使界定格式化简单一些,咱们假定有一个匿名块盒 Anonymous Block Box 围绕在“Some text”周围。

2VCvqi4.png

该例如图所示,有三个盒,其中一个为匿名盒。

换句话说:若是一个块容器盒(如上例中为 div 生成的盒)内有一个块级盒(如上例中的 p ),那么咱们强制它只包含块级盒。

当一个行内盒 inline box 包含一个文档流内 In-flow 的块级盒,这个行内盒(及在同一行盒的 Line Box 它的行内祖先)会在该块级盒(及其连续的或者中间只被可折叠空白、脱离文档流元素分隔的块级同胞)的周围打断,把行内盒分离成两个盒(甚至一边为空也如此),各在块级盒一边。在打断以前和打断以后的行盒 Line Box 都被匿名块盒包含,而且该块级盒成为匿名块盒的同胞。当这样的行内盒受到相对定位影响,任何产生的移动一样影响到包含在其中的块级盒。

该模型将应用在下面的例子中。假设有规则以下:

p    { display: inline }
span { display: block }

被应用到以下HTML文档:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Anonymous text interrupted by a block</title>
</head>
<body>
   <p>
      This is anonymous text before the SPAN。
      <span>This is the content of SPAN.</span>
      This is anonymous text after the SPAN。
   </p>
</body>
</html>

p 元素包含一段匿名文本 C1 ,接着是一个块级元素,随后又是另外一段匿名文本 C2 。结果生成了一个表明 body 的块盒,它包含了围绕 C1 一个匿名块盒、 span 的块盒,和围绕 C2 的另外一个匿名块盒。

匿名盒的继承属性会从包含它的非匿名盒那里继承(好比,在子节标题“匿名块盒”下的那个例子中的 div 盒)。匿名盒的非继承属性将取其初始值。例如,匿名盒的字体属性继承自 div ,可是外边距是 0

当一个元素致使了匿名块盒的生成,则该元素上设置的属性同样能应用于该元素生成的盒和该元素的内容。例如,在上面例子中,若是在 p 元素上设置了边框,则这个边框将画在 C1 (在行的结尾开)和 C2 (在行的结尾闭)周围。

xpiKFXw.png

一些用户代理用其它方式实现了行内包含块 Inlines Containing Blocks 上的边框。例如,将其内嵌的块放入“匿名行盒”中,并在这些匿名行盒周围绘出行内边框。因为CSS1和CSS2没有定义这种表现,仅支持CSS1或CSS2的用户代理才会以其它形式来实现,并仍声称遵照这部分CSS2.1规范。对于CSS2.1规范发布以后的用户代理不会这么作。

IE6下的效果:

Z63OR8A.png

计算百分比值时,应忽略匿名块盒,而以最近的非匿名祖先盒来替代。例如,上面的 div 里,若是一个匿名块盒的子盒在须要知道其包含块的高度来得到一个百分比高度。那么它将使用 div 造成的包含块的高度,而不是匿名块盒的高度。

9.2.2 行内级元素 Inline-level Elements 和 行内盒 Inline Boxes

行内级元素是在源文档中那些不为其内容造成新的块、其内容分布在多行中的元素(如,段落内着重文本,行内图片等等)。如下的 display 属性值产生一个行内级元素: inline inline-table ,以及 inline-block 。行内级元素生成行内级盒 Inline-level Boxes ,而这些盒会参与行内格式化上下文 Inline Formatting Context

一个行内盒是行内级盒,且其内容参与了该行内盒的行内格式化上下文。一个 display 值是 inline 的不可替换元素会生成一个行内盒。那些不是行内盒的行内级盒(例如可替换的行内级元素 Replaced Inline-level Elements 、行内块元素 inline-block 、行内表格元素 inline-table )被称为原子行内级盒 Atomic Inline-level Boxes ,由于它们以单一不透明盒的形式来参与它们的行内格式化上下文。

KVmfRh8.png

9.2.2.1 匿名行内盒 Anonymous Inline Boxes

任何被直接包含在一个块容器元素(不是包含在行内元素)的文本必须做为匿名行内元素来对待。

一个HTML文档以下:

<p>Some <em>emphasized</em> text</p>

p 产生一个块盒,其中包含了一些行内盒。 emphasized 的盒是一个由行内元素 em 生成的行内盒,但其余盒( some text 的)是由块级元素 p 生成的行内盒。后面这种盒被称做匿名行内盒,由于它们没有相关的行内级元素。

这些匿名行内盒的可继承属性将从它们的父级块盒中继承。非继承性属性取其初始值。在上面例子中,匿名行内盒的 color p 那里继承,但 background transparent

空白内容,根据 white-space 属性,若是可被折叠则不会产生任何匿名行内盒。

本规范中,若是可根据上下文来清晰界定一个匿名盒的类型,则匿名行内盒和匿名块盒均可被简称为匿名盒。

在格式化表格时,还会有更多类型的匿名盒出现。

9.2.3 Run-in Boxed 插入盒

为使章节号同以前的草案一致,特保留此节。 display: run-in 现已定义至CSS3(参见CSS基本盒模型)。

9.2.4 display 属性

(译者注:本处暂只记录常见几个值的简略介绍)

  1. block 元素产生一个块盒。

  2. inline-block 元素产生一个行内级块容器。行内块的内部会被看成块盒来格式化,而此元素自己会被看成原子行内级盒来格式化。

  3. inline 元素产生一个或多个的行内框。

  4. none 元素不出如今格式化结构中(也就是说,在视觉媒体中元素既不产生盒也不影响布局)。其后代元素也不产生任何盒:该元素及其内容会被从格式化结构中彻底移除。对后代元素设定 display 属性不能覆盖这个表现。

请注意 none 值不产生可见盒;它根本就不生成盒。CSS中有使元素在格式化结构中产生盒并影响格式化,但盒自己不可见的机制。请访问visibility的章节了解详情。

除定位元素和浮动元素以及根元素外(见下文)计算值与指定值相同。根元素的计算值按下文所述改变。

注意,尽管 display 初始值是 inline ,但用户代理的默认样式表规则可能覆盖该值。请见附录中的HTML4参考样式表。

9.3 定位体系 Positioning Schemes

在CSS2.1中,盒子根据如下三种体系来布局:

  1. 常规流 Normal Flow 。CSS2.1中,常规流包括块级盒的块格式化,行内盒的行内格式化,以及块级盒和行内级盒的相对定位。

  2. 浮动 Floats 。在浮动模型中,盒首先根据常规流布局,而后从常规流中脱离并尽量地向左或向右位移。内容能够布局在浮动周围。

  3. 绝对定位 Absolutr Positioning 。在绝对定位模型中,盒彻底从常规流中脱离(对后面的同胞元素无影响)并根据包含块来分配位置。

浮动元素、绝对定位元素、根元素都被称为脱离文档流 Out of Flow ;其余元素被称为文档流内 In-flow 。元素 A 的排版流由 A 、在文档流内且最近的脱离文档流的祖先是A的元素构成。

9.3.1 选择定位体系: position 属性

(译者注:本节翻译有省略)

  1. static:盒为常规盒,根据常规流布局, top right bottom left 属性不生效。

  2. relative:盒的定位根据常规流计算(盒被成为常规流内定位)。接着盒相对其常规位置移动。当B盒相对定位,B盒以后的盒定位时就当B没有移动同样来计算。 table-row-group table-header-group table-footer-group table-row table-column-group table-column table-cell 以及 table-caption 上次未定义此效果。

  3. absolute:盒的位置(还可能包括大小)由 top right bottom left 属性指定。这些属性根据盒的包含块来规定移动。绝对定位盒脱离文档流。这意味着它们对以后的同胞盒的布局没有影响。同时,即使绝对定位盒有外边距,也不一样其余任何外边距折叠。

  4. fixed:盒的定位根据 absolute 模型来计算,但除此以外,盒相对某些参照物保持固定。和 absolute 模型同样,此盒的外边距也不一样其余任何外边距折叠。在手持 handheld 、投影 projection 、屏幕 screen 、打字机 tty 、电视 tv 媒体类型中,盒相对视口固定且滚动时不会移动。在打印媒体类型中,即使页面是经过视口来访问的(好比打印预览),盒也渲染在全部页,而且根据页盒固定。其余媒体类型中则未定义此表现。开发者可根据依赖媒体来指定 fixed 。好比说,若是想使盒固定在屏幕视口顶部,但不出如今打印页的顶部,这两种设定能够经过使用@media规则来分开,以下:

@media screen { 
   h1#first { position: fixed } 
}
@media print { 
   h1#first { position: static }
}

用户代理不可将固定盒的内容分页显示。注意用户代理可能用其余方法打印不可见内容。参见第13章“页盒外的内容”。

用户代理可将根元素上的 position 视为 static

9.3.2 盒位移 Box Offsets: top right bottom left

(译者注:本节暂略,可参考CSS手册)

9.4 常规流 Normal Flow

常规流中的盒子都属于某个格式化上下文,要么块格式化上下文,要么行内格式化上下文,总之不能两者得兼。块级盒参与块格式化上下文,行内级盒参与行内格式化上下文。

9.4.1 块格式化上下文

浮动、绝对定位元素、非块盒的块容器(如:行内块 inline-block 、表格单元格 table-cell 以及表格标题 table-caption )以及 overflow 属性不为 visible 的块盒(除了该值被传播到视口的状况)将为其内容建立一个新的块级格式化上下文。

在块格式化上下文中,盒从包含块顶部一个接一个地垂直摆放。两个同胞盒间的垂直距离取决于 margin 属性。同一个块格式化上下文中的相邻块级盒的垂直外边距将折叠。

在块格式化上下文中,每一个盒的左外边缘紧贴包含块的左边缘(从右到左的格式里,则为盒右外边缘紧贴包含块右边缘),甚至有浮动也是如此(尽管盒里的行盒可能因为浮动而收缩),除非盒建立了一个新的块格式化上下文(在这种状况下盒子自己可能因为浮动而变窄)。

关于在页面媒体 Paged Media 中分页的信息,请参考容许页面分页的章节。

9.4.2 行内格式化上下文

在行内格式化上下文中,盒从包含块的顶部一个接一个地水平摆放。盒水平方向的外边距、边框和内边距在布局时都会考虑在内。盒的垂直对齐方式则不一:可能按底部或者顶部对齐,又或者按它们内容文本的基线对齐。包含了一行里全部盒的矩形区域被称为行盒 Line Box

行盒的宽度取决于包含块以及浮动。行盒的高度取决于在行盒高度计算章节所给出的规则。

行盒的高老是足以容纳其包含的全部盒。然而,它可能高于其所包含的最高盒(好比,包含的盒以基线对齐)。当一个盒( B )的高度小于包含它的行盒的高度时, B 的垂直对齐方式由 vertical-align 属性决定。当在水平方向上几个行内级盒不能彻底被单个行盒包含时,它们会被分配到两个或者多个垂直摆放的行盒中。所以,一个段落就是多个行盒的垂直堆叠。行盒的堆叠没有垂直间距(除非有特别声明)而且从不重叠。

通常来讲,行盒的左边缘紧贴其包含块的左边缘,其右边缘紧贴包含块的右边缘。然而,浮动盒可能被置于包含块和行盒边缘之间。所以,尽管在同一行内格式化上下文中的行盒是等宽的(包含块的宽度),因为浮动会形成可用的水平空间减小,行盒的宽度仍可能变更。同一行内格式化上下文中的行盒在高度上一般是变更的(好比,一行可能包含图片但其余行仅包含文本)。

当一行中的行内级盒的总宽度小于包含它们的包含块的时候,它们在行里的水平分布取决于 text-align 属性。若是取 justify 值,用户代理可能拉伸行内盒( inline-table inline-block 盒除外)中的空格和字间距。

当行内盒的宽度超过行盒宽度时,行内盒将被分为多个盒,被分解出的盒则又分布在多个行盒中。若是一个行内盒不可切割(好比,行内盒包含的是单个字符或者语言指定的断字规则不容许断字,又或者行内盒的 white-space 属性值为 nowrap pre ),那么该行内盒将溢出行盒。

当行内盒被分割,外边距、边框和内边距在任何断点处都不会产生视觉影响。

行内盒也可能因为双向文本处理而在一个行盒内被切割成多个盒。

为了包含行内格式化上下文中的行内级内容,行盒按需建立。有的行盒不包含文本、保留空白、外边距或内边距或边框不为零的行内元素、其余文档流内 In-flow 内容(如图片、行内块或行内表格),而且不以保留的换行符结尾,若是是为决定它们所包含的元素的定位,则必须视其为零高度的行盒,除此以外的其余目的下应视其为不存在。

下面是一个行内盒构造的例子。下属的段落(由HTML块级元素 p 建立)包含了有 em strong 交叉的匿名文本。

<p>Several <em>emphasized words</em> appear
<strong>in this</strong> sentence, dear.</p>

p 元素生成了一个块盒来包含五个行内盒,其中三个行内盒是匿名的:

  • 匿名:"Several"

  • em:"emphasized words"

  • 匿名:"appear"

  • strong:"in this"

  • 匿名:"sentence, dear."

为了格式化该段落,客户端将五个行内盒放进行盒。在这个例子中,由 p 元素生成的盒建立了行盒的包含块。若是该包含块足够宽,全部的行内盒将放置在单个行盒:

Several emphasized words appear in this sentence, dear.

若是宽度不够,行内盒就会被分割并分布在多个行盒。段落可能就变成了:

Several emphasized words appear

in this sentence, dear.

或者:

Several emphasized

words appear in this

sentence, dear.

在最后这个状况里, em 盒被分割成了两个 em 盒(现称之为 split1 split2 )。外边距、边框、内边距或者文本修饰在 split1 以前或者 split2 以后都没有视觉效果。

看下面这个例子:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Example of inline flow on several lines</title>
<style type="text/css">
   EM {
      padding: 2px; 
      margin: 1em;
      border-width: medium;
      border-style: dashed;
      line-height: 2.4em;
   }
</style>
</head>
<body>
<p>Several <em>emphasized words</em> appear here.</p>
</body>
</html>

根据 p 的宽度,这些盒可能分布以下:

NUuaQrm.png

  • 外边距插在了 emphasized 以前和 words 以后

  • 内边距被插在了 emphasized 以前、上、下, words 值后、上、下。虚线边框渲染在了每一个单词的三边。

9.4.3 相对定位 Relative Positioning

一旦一个盒遵循常规流或者浮动而布局好位置后,它有可能根据这个位置来相对位移。这被称做相对定位。经过这种方式移动盒( B1 )对随后的盒( B2 )没有影响: B2 被赋予了一个如同 B1 没有位移的位置,而且 B2 B1 移动后不会重定位。这意味着相对定位可能形成盒重叠。然而,若是相对定位形成一个 overflow:auto overflow:scroll 的盒溢出,客户端必须经过建立滚动条来让用户能够访问到该内容(在其偏移位置),这可能影响布局。

一个相对定位盒保持其常规流中的大小,包括断行和本来为其保留的空间。包含块一节解释了相对定位盒建立新的包含块的状况。

对于相对定位元素而言, left right 在不改变盒大小的同时使其水平位移。 left 使盒向右移动, right 时期向左。 left right 没有形成盒的分割或拉伸,所以应用的值始终知足: left = - right

若是 left right 值均为 auto (其默认值),应用的值为 0 (便是说,盒保持在其原位)。

若是 left auto ,其应用值为 right 的负值(即盒向左移动 right 值)。

若是 right auto ,其应用值为 left 的负值。

若是 left right 均不为 auto ,定位则被过分约束,其中一值必须被忽略。若是包含块的 direction 属性值为 ltr ,则 left 值胜出而 right 值改成 - left 。若是包含块的 direction 属性值为 rtl right 值胜出而 left 值被忽略。

举例。下面三条样式规则是等效的。

div.a8 {
   position: relative;
   direction: ltr;
   left: -1em;
   right: auto
}
div.a8 {
   position: relative;
   direction: ltr;
   left: auto;
   right: 1em
}
div.a8 {
   position: relative;
   direction: ltr;
   left: -1em;
   right: 5em
}

top bottom 属性在不改变相对定位元素的大小的同时使其上下位移。 top 使其下移, bottom 则使其上移。 top bottom 没有形成盒的分割或拉伸,所以应用的值始终知足: top = - bottom 。若是两者均为 auto ,其值则均为 0 。若是其中一个值为 auto ,则该属性取另外一属性的负值。若是两者均不为 auto bottom 将被忽略(也就是说, bottom 应用值为 top 的负值)。

注:在脚本环境中动态移动相对定位盒能够产生动画效果(见 visibility 属性)。尽管相对定位可被用于上标和下标效果,但行高在自动调整时不会将其定位归入计算。参见行高计算一节的描述了解更多信息。

相对定位的例子将在对比常规流、浮动和相对定位一节中提供。

9.5 浮动 Floats

在当前行中一个盒被移动到左侧或右侧称为浮动。浮动最有趣的特色是内容能够布局在其旁边(或者为 clear 属性所禁止)。内容会布局在左浮动盒的右侧,或布局在右浮动盒的左侧。下述内容是对浮动定位及内容布局的介绍。控制浮动行为的准则已经在 float 属性一节中描述。

浮动盒将被移动至左侧或右侧直至其外侧紧贴包含盒的边缘或另一个浮动的外边缘。若是存在行盒,浮动盒的顶部外边缘将与行盒的顶部对齐。

若是水平方向没有足够的空间容纳浮动,它将下移直至可以放下它或者没有其余浮动。

因为浮动不在常规流中,在浮动以前或以后建立的非定位块盒将垂直摆放,如同浮动不存在同样。然而,当前行盒和随浮动后建立的行盒会按需缩短来为浮动的外边距盒腾出空间。

当有一个垂直定位知足如下所有四个条件时,行盒将紧挨着浮动:

  1. 在行盒顶部或之下

  2. 在行盒底部或之上

  3. 在浮动的上外边距边缘之下,并

  4. 在浮动下外边距边缘之上

注:这意味着总高度 Outer Height 为零或为负的浮动不会缩短行盒。

若是行盒被缩短到不能容纳任何内容,那么行盒将下移(其宽度会从新计算)直到能够容纳内容或再也不有浮动。当前行中,任何在浮动盒以前的内容将移动到同一行中的浮动的另外一侧从新布局。换句话说,若是行内级盒先于左浮动被放在行盒中,而行盒的剩余空间能够容纳左浮动,那么左浮动会被置于该行内,且与行盒顶部对齐,而已经放入该行盒的行内级盒会被相应地移动到浮动的右侧(右侧便是左浮动的另外一侧),反过来对 rtl 和右浮动也是这样。

表格、块级可替换元素或者在常规流中建立新的块格式化上下文的元素(如 overflow 值非 visibile 的元素),它们的边框盒不可与它们同属一个块格式化上下文中的浮动元素的外边距盒重叠。若是有必要的话,应当经过把它们置于已出现的浮动的后面达到清除浮动的效果,但若是空间足够,能够将其放置在浮动旁边。但这可能使得该元素的框盒变得比10.3.3章节定义的还要窄。CSS2没有定义用户代理什么时候能够把元素置于浮动旁的状况,也没有定义元素会变得多窄的状况。

举例。在下面的文档片断中,包含块不足以容纳浮动旁边的内容,所以内容须要移动到浮动下面,并根据其 text-align 属性来在行盒中定位。

p {
   width: 10em;
   border: solid aqua;
}
span {
   float: left;
   width: 5em;
   height: 5em;
   border: solid blue;
}

<p>
   <span> </span>
   Supercalifragilisticexpialidocious
</p>

该片断可能以下图所示:

VuMC2rw.png

浮动能够并列,而这个模型也适用于同一行中的并列浮动元素。

下面的规则会使全部的 class="icon" img 盒浮动到左侧(并设左外边距为 0 )。

img.icon { 
   float: left;
   margin-left: 0;
}

考虑以下HTML代码和样式表:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Float example</title>
<style type="text/css">
   img { float: left }
   body, p, img { margin: 2em }
</style>
</head>
<body>
   <p><img src=img.png alt="This image will illustrate floats">
   Some sample text that has no other...
</body>
</html>

img 盒左浮动。其后的内容被格式化到浮动的右侧,从浮动所在的同一行开始布局。挨着浮动的行盒因为浮动之故缩短,但浮动以后就恢复了它们“正常”宽度(即 p 元素建立的包含块之宽)。该文档格式化以下:

ReZKRqp.png

若是文档以下,格式化的结果是同样的:

<body>
   <p>Some sample text 
   <img src=img.png alt="This image will illustrate floats">
   that has no other...
</body>

这是由于浮动左侧的内容为浮动所替代,并被从新布局在了浮动的右侧。

正如8.3.1节开头所言,浮动元素的外边距不会同相邻盒的外边距折叠。所以,在以前的例子中, p 盒和 img 浮动盒的垂直外边距不会折叠。

浮动的内容会像浮动建立了新的堆叠上下文 Stacking Context 同样堆叠起来,但定位元素、建立了新的堆叠上下文并参与了浮动的父级堆叠上下文并的元素除外。浮动能够同常规流中的其余盒重叠(好比,浮动旁边的常规流盒有负外边距的时候)。当发生重叠时,浮动会被渲染在非定位文档流内块 Non-positioned In-flow Blocks 之上,文档流内行内盒之下。

这有个例子,演示了浮动与常规流中元素的边框重叠的状况。

4SAJKo0.png

浮动图片挡住了与其重叠的块盒的边框

下一个例子演示了使用 clear 属性阻止内容布局在浮动旁边。

假设规则以下:

p { clear: left }

格式化结果可能以下所示:

u8za9UD.png

两个段落都设置了 clear: left ,所以使得第二个段落“被往下推”到浮动之下的位置,这是“空隙”被添加到其上外边距之上的结果(见 clear 属性)

9.5.1 浮动定位: float 属性

(译者注:此处暂略,可参见CSS手册)

用户代理能够视根元素上的 float none

如下是控制浮动行为的准则:

  1. 左浮动盒的左外边缘不可在其包含块的左边缘之左。右浮动元素亦是。

  2. 若是当前盒左浮动,而此前源文档中已有元素生成了左浮动盒,那么对每一个此前生成的盒而言,要么当前盒的左外边缘在此前生成盒的右外边缘之右,要么当前盒的顶部必须低于此前生成盒的底部。右浮动元素亦是。

  3. 左浮动盒的右外边缘不可在其旁边的右浮动盒的左外边缘之右。右浮动元素亦是。

  4. 浮动盒的上外边缘不可高于其包含块的顶部。当浮动出现两个折叠外边距之间时,浮动会如同它有一个参与常规流的空匿名父块同样来定位。该父块的位置由关于外边距折叠那章的规则规定。

  5. 浮动盒的上外边缘不可高于源文档中此前元素生成的块盒或浮动盒的上外边缘。

  6. 元素的浮动盒的上外边缘不可高于源文档中此前元素生成的盒所在的行盒的顶部。

  7. 一个左浮动盒若是有其余左浮动盒在其左侧,其右外边缘不可在其包含块的右边缘之右。(宽松点的要求是:左浮动不可超出其包含块的右边缘,除非该盒已经尽量靠左了。)右浮动元素亦是。

  8. 浮动盒必须尽量地往高摆放。

  9. 左浮动盒的摆放必须尽量地靠左,右浮动盒必须尽量靠右。更高的位置优先于更靠近左/右的位置。

lI6ls55.png

可是在CSS2.1中,若是,在块格式化上下文中,有一个文档流内负垂直高度的外边距,使得浮动的位置高于它本来应当在的位置,全部这种负外边距被设为零,浮动的位置则未定义。

这些规则中提到的其余元素仅指:在和浮动同属一个块格式化上下文的其余元素。

这个HTML片断结果为 b 向右浮动

<p>a<span style="float: right">b</span></p>

若是 p 元素足够宽, a b 则会各执一边,以下所示:

RRkbQCc.png

9.5.2 控制浮动后的流: clear 属性

(译者注:属性介绍略,可参看CSS手册)

该属性指定元素的某侧不容许同此前的浮动盒相邻。 clear 属性不考虑其自己内的浮动或者处于其余块格式化上下文的浮动。

各值被应用于非浮动块级盒时,具备以下意义:

  1. left:要求盒的上边框边缘低于源文档内此前元素生成的左浮动盒的下外边缘。

  2. right:要求盒的上边框边缘低于源文档内此前元素生成的右浮动盒的下外边缘。

  3. both:要求盒的上边框边缘低于源文档内此前元素生成的左、右浮动盒的下外边缘。

  4. none:对盒相对于浮动的定位没有约束。

none 值可能产生空隙 Clearance 。空隙阻止外边距折叠并充当元素上外边距之上的空间。空隙被用于推进元素垂直越过浮动。

计算设置了 clear 值的元素的空隙,首先要计算元素上边框边缘的假定位置,该位置即元素 clear 属性值为 none 时实际上边框边缘应该在的位置。

若是元素上边框边缘的假定位置没有越过有关浮动,那么空隙就会产生,而且外边距折叠要根据8.3.1章规则计算。

空隙的高度被设为下述中的较大值:

  1. 块的边框边缘与要被清除的最下方的浮动的下外边缘不相交的必要高度。

  2. 将块的上边框边缘放在其假定位置的必要高度。

二选一的话,空隙高度即第一种。

注意:两种方式在目前的网页内容的兼容性上有待评估。将来的CSS规范将规定为其中一个或另外一个。

注意:空隙能够为负或为零。

例1:假设(为求简单)有三个盒,规定以下: B1 块的下外边距为 M1 B1 没有子元素也没有内边距和边框);浮动块 F 的高度为 H B2 块上外边距为 M2 (没有内边距或边框,没有子元素)。 B2 clear 设为 both 。假设 B2 不为空。

不考虑 B2 clear 属性,状况以下图所示。 B1 B2 的外边距折叠。 B1 的下边框边缘处在 y = 0 的位置, F 的顶部处在 y = M1 的位置, B2 的上边框边缘处在 y = max(M1,M2) 的位置, F 的底部处于 y = M1+H 的位置。

kjeqVI0.png

同时假设 B2 不在 F 之下:

max(M1,M2)

也就是说,正如规范说明的状况,咱们须要添加空隙。

咱们须要两次计算空隙 C1 C2 ,并取两者之大: C = max(C1,C2) 。第一种方法是把 B2 的顶部和 F 的底部齐平,即,放在 y= M1+H 。也意味着外边距之间的空隙使得外边距再也不折叠:
F 的底部 = B2 的上边框边缘 ⇔

M1 + H = M1 + C1 + M2 ⇔

C1 = M1 + H - M1 - M2 = H - M2

第二次计算是保持 B2 顶部位置,即 y=max(M1,M2) 处,即:

max(M1,M2) = M1 + C2 + M2 ⇔

C2 = max(M1,M2) - M1 - M2

假设 max(M1,M2)

C2 = max(M1,M2) - M1 - M2

C2

又由于 C1 = H - M2,得

C2

因此

C = max(C1,C2) = C1

例2:本例中空隙的高度为负,-1em。(假设全部元素都没有边框或者内边距)

<p style="margin-bottom: 4em">
   First paragraph.
</p>
<p style="float: left; height: 2em; margin: 0">
   Floating paragraph.
</p>
<p style="clear: left; margin-top: 3em">
   Last paragraph.
</p>

说明:要是没有 clear ,首段和末段两个段落的边距将会折叠而且末段的上边框边缘将同浮动段落的顶部齐平。但 clear 使得上边框边缘低于浮动,即,降低2em。这意味着必定会产生空隙。由此,外边距再也不折叠,空隙的高度 clearance 知足

clearance + margin-top = 2em

也就是说,

clearance = 2em - margin-top = 2em - 3em = -1em

clear 设在浮动元素上时,将形成浮动定位规则的修正。第10条额外规定补充以下:

  • (当 clear 设在浮动元素上时,)浮动的上外边缘必须低于全部此前左浮动盒的下外边缘( clear: left 情形下),或者低于全部此前的右浮动盒的( clear: right 情形下),或者低于此前左右浮动盒的( clear: both 情形下)。

注意:CSS1中该属性适用于全部元素,所以全部元素都能实现效果。在CSS2和CSS2.1中, clear 属性仅支持块级元素。所以开发者们应当只将此属性应用于块级元素。若是要实现行内元素清除浮动效果,不该当如上所讲的去设置空隙,而应当强制断行并插入一个或多个空行盒(或者如9.5章节所讲移动新行盒)来使要清除浮动的行内元素的行盒低于浮动盒。

9.6 绝对定位 Absolute Positioning

在绝对定位模型中,盒根据其包含块来精准位移。盒从常规流中彻底脱离(对后来的同胞元素没有影响)。绝对定位盒为其常规流的子元素和绝对定位(非固定定位)后代建立新的包含块。然而,绝对定位元素的内容不在其余盒的流中。取决于重叠盒的栈级 Stack Level ,绝对定位元素的内容可能遮挡其余盒的内容(或被遮挡)。

9.6.1 固定定位 Fixed Positioning

固定定位是绝对定位的一种下属体系。惟一的区别在于,固定定位盒的包含块是由视口建立的。在连续媒体中,当文档滚动时,固定盒不移动。在此意义上,它们同固定背景图片相像。在页面媒体中,固定定位盒在每一页重复。这对布局颇有用,好比,摆放每页底部的标识。比页面区域要大的固定定位盒将会被裁切。固定定位盒在初始化包含块中不可见的部分将不会打印。

开发者可使用固定定位去建立类框架布局。考虑以下框架布局:

JG4nG5f.png

这能够经过以下HTML文档和样式规则实现:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>A frame document with CSS 2.1</title>
<style type="text/css" media="screen">
   body { height: 8.5in }/* 计算百分百高度须要 */
   #header {
      position: fixed;
      width: 100%;
      height: 15%;
      top: 0;
      right: 0;
      bottom: auto;
      left: 0;
   }
   #sidebar {
      position: fixed;
      width: 10em;
      height: auto;
      top: 15%;
      right: auto;
      bottom: 100px;
      left: 0;
   }
   #main {
      position: fixed;
      width: auto;
      height: auto;
      top: 15%;
      right: 0;
      bottom: 100px;
      left: 10em;
   }
   #footer {
      position: fixed;
      width: 100%;
      height: 100px;
      top: auto;
      right: 0;
      bottom: 0;
      left: 0;
   }
</style>
</head>
<body>
   <div id="header"> ...  </div>
   <div id="sidebar"> ...  </div>
   <div id="main"> ...  </div>
   <div id="footer"> ...  </div>
</body>
</html>

9.7 display position float 之间的关系

三种属性均影响盒生成及布局,它们的交互以下:

  1. 若是 display 值为 none ,那么 position float 不会应用。这种状况下,元素不生成盒。

  2. 不然,若是 position 值为 absolute fixed ,盒为绝对定位, float 的计算值为 none display 的设值以下表。盒的位置由 top right bottom left 属性以及盒的包含块决定。

  3. 不然,若是 float 值不为 none ,盒浮动且 display 的设值以下表。

  4. 不然,若是元素为根元素, display 设值以下表,除了其在CSS2.1中未定义 list-item 的指定值是否变为计算值 block list-item

  5. 不然, dislay 属性值使用指定值。

对应表:

  • 指定值:inline-table

  • 计算值:table

  • 指定值:inline, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block

  • 计算值:block

  • 指定值:其余

  • 计算值:同指定值

相关文章
相关标签/搜索