10 可视化格式模型细节

内容

注意:本规范的若干章节已被其他规范更新。请参阅最新 CSS Snapshot 中的 “层叠样式表 (CSS) — 官方定义”,其中列出了规范以及它们取代的章节。

CSS 工作组也在开发 CSS 2 级修订版 2(CSS 2.2)

10.1 “包含块”的定义

元素的盒子(或多个盒子)的定位和尺寸有时是相对于某个矩形计算的,该矩形称为元素的 包含块。元素的包含块定义如下

  1. 根元素所在的包含块是一个矩形,称为 初始包含块。对于连续介质,它的尺寸与视口相同,并且锚定在画布原点;对于分页介质,它是页面区域。初始包含块的 ‘direction’ 属性与根元素相同。
  2. 对于其他元素,如果元素的 position 为 ‘relative’ 或 ‘static’,包含块由最近的块容器祖先盒子的内容边缘形成。
  3. 如果元素的 position 为 ‘fixed’,则在连续介质的情况下包含块由视口建立,在分页介质的情况下由页面区域建立。
  4. 如果元素的 position 为 ‘absolute’,则包含块由最近的具有 ‘position’ 为 ‘absolute’、‘relative’ 或 ‘fixed’ 的祖先建立,方式如下
    1. 若祖先是行内元素,则包含块是该元素生成的首个和最后一个行内盒子的填充盒子所包围的边界框。CSS 2.1 中,如果行内元素跨多行拆分,则包含块未定义。
    2. 否则,包含块由祖先的填充边缘形成。

    如果不存在这样的祖先,包含块就是初始包含块。

在分页介质中,绝对定位元素相对于其包含块定位,忽略任何分页断点(仿佛文档是连续的)。该元素随后可能跨多个页面断开。

对于解析后位于正在布局的页面(当前页)之外的页面,或已经在当前页渲染用于打印的绝对定位内容,打印机可以将内容

注意,跨多个页面的块级元素在每页上的宽度可能不同,并且可能受到设备特定的限制。

示例

在没有定位的情况下,下面文档中的包含块(C.B.)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
   <HEAD>
      <TITLE>Illustration of containing blocks</TITLE>
   </HEAD>
   <BODY id="body">
      <DIV id="div1">
      <P id="p1">This is text in the first paragraph...</P>
      <P id="p2">This is text <EM id="em1"> in the 
      <STRONG id="strong1">second</STRONG> paragraph.</EM></P>
      </DIV>
   </BODY>
</HTML>

如下确定:

由以下生成的框: C.B. 由以下确定:
html初始 C.B.(用户代理依赖)
bodyhtml
div1body
p1div1
p2div1
em1p2
strong1p2

如果我们定位 "div1"

   #div1 { position: absolute; left: 50px; top: 50px }

它的包含块不再是 “body”;它变为初始包含块(因为没有其他定位的祖先盒子)。

如果我们同样定位 "em1"

   #div1 { position: absolute; left: 50px; top: 50px }
   #em1  { position: absolute; left: 100px; top: 100px }

包含块表将变为

由以下生成的框: C.B. 由以下确定:
html初始 C.B.(用户代理依赖)
bodyhtml
div1初始 C.B.
p1div1
p2div1
em1div1
strong1em1

通过定位 "em1",它的包含块变为最近的定位祖先框(即由 "div1" 生成的框)。

10.2 内容宽度'width' 属性

'width'
  <length> | <percentage> | auto | inherit
初始值  auto
应用于  所有元素,但不包括非替换的行内元素、表行和行组
可继承  
百分比  参考包含块的宽度
媒体  视觉
计算值  指定的百分比或 ‘auto’,或绝对长度

此属性指定盒子的内容宽度

此属性不适用于非替换的行内元素。非替换行内元素盒子的内容宽度等于其内部渲染内容的宽度(子元素的相对偏移之前)。请记住,行内盒子流入行盒子。行盒子的宽度由它们的包含块决定,但可能因浮动的存在而被缩短。

值的含义如下:

<length>(长度)
使用长度单位指定内容区域的宽度。
<percentage>(百分比)
指定百分比宽度。百分比相对于生成盒子的包含块的宽度计算。如果包含块的宽度取决于该元素的宽度,则在 CSS 2.1 中导致布局未定义。 注:对于包含块基于块容器元素的绝对定位元素,百分比相对于该元素的填充盒宽度计算。这与 CSS1 不同,后者始终相对于父元素的内容盒计算百分比宽度。
auto
宽度取决于其他属性的值。见下文各节。

'width'使用负值是非法的。

示例

例如,下面的规则将段落的内容宽度固定为 100 像素

p { width: 100px }

10.3 计算宽度和外边距

元素的'width''margin-left''margin-right''left''right'属性在布局中的取值取决于生成的盒子类型以及彼此之间的关系。(用于布局的值有时称为已使用值。)原则上,使用的值与计算值相同,只是将 ‘auto’ 替换为适当的值,百分比基于包含块计算,但也有例外。需区分以下情况:

  1. 行内,非替换元素
  2. 行内,替换元素
  3. 块级,非替换元素(正常流)
  4. 块级,替换元素(正常流)
  5. 浮动,非替换元素
  6. 浮动,替换元素
  7. 绝对定位,非替换元素
  8. 绝对定位,替换元素
  9. ‘inline-block’,非替换元素(正常流)
  10. ‘inline-block’,替换元素(正常流)

对于点 1‑6 与 9‑10,若元素相对定位,则 ‘left’ 与 ‘right’ 的已使用值由第 9.4.3 节的规则决定。

注意。 下面计算的 ‘width’ 已使用值是暂定值,可能需要多次计算,取决于'min-width''max-width',见下文 最小与最大宽度 一节。

10.3.1 行内,非替换元素

‘width’ 属性不适用。若 'margin-left''margin-right' 的计算值为 ‘auto’,则其已使用值为 ‘0’。

10.3.2 行内,替换元素

'margin-left''margin-right' 的计算值为 ‘auto’,其已使用值为 ‘0’。

如果 'height''width' 都为 ‘auto’,且元素具有固有宽度,则该固有宽度即为 'width' 的已使用值。

如果 'height''width' 都为 ‘auto’,且元素没有固有宽度,但具有固有高度和固有比例;或者 'width' 为 ‘auto’,'height' 为其他计算值且元素具有固有比例;则 'width' 的已使用值为

(used height) * (intrinsic ratio)

如果 ‘height’ 与 'width' 都为 ‘auto’,且元素拥有固有比例但没有固有高度或宽度,则在 CSS 2.1 中 ‘width’ 的已使用值未定义。不过建议:如果包含块的宽度本身不依赖于替换元素的宽度,则 ‘width’ 的已使用值可依据块级、非替换元素在正常流中的约束方程计算。

否则,如果 'width' 的计算值为 ‘auto’,且元素有固有宽度,则该固有宽度即为已使用值。

否则,如果 'width' 为 ‘auto’,且上述条件均不满足,则已使用值为 300px。如果 300px 对设备来说过宽,UA 应采用能够适配设备且具有 2:1 比例的最大矩形宽度。

10.3.3 块级,非替换元素(正常流)

以下约束必须在其他属性的已使用值之间成立

'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = 包含块的宽度

如果 ‘width’ 不是 ‘auto’,且 ‘border-left-width’ + ‘padding-left’ + ‘width’ + ‘padding-right’ + ‘border-right-width’(再加上任何不是 ‘auto’ 的 ‘margin-left’ 或 ‘margin-right’)的总和超过包含块的宽度,则在后续规则中,所有 ‘auto’ 的 ‘margin-left’ 或 ‘margin-right’ 视为 0。

如果上述所有值均为非 ‘auto’ 的计算值,则称它们为“约束过度”,必须让其中一个已使用值不同于其计算值。若包含块的 'direction' 为 ‘ltr’,则忽略 'margin-right' 的指定值,并计算使等式成立的值。若 'direction' 为 ‘rtl’,则对 'margin-left' 进行相同处理。

如果恰好有一个值被指定为 ‘auto’,则其已使用值由等式直接求得。

如果 ‘width’ 被设为 ‘auto’,则所有其他的 ‘auto’ 值变为 ‘0’,并从结果等式求得 ‘width’ 的已使用值。

如果 'margin-left''margin-right' 均为 ‘auto’,则它们的已使用值相等,从而实现元素在包含块左右边缘之间的水平居中。

10.3.4 块级,替换元素(正常流)

‘width’ 的已使用值按 行内替换元素 的方式确定。随后对非替换块级元素的规则适用以确定外边距。

10.3.5 浮动,非替换元素

如果 'margin-left''margin-right' 的计算值为 ‘auto’,则其已使用值为 ‘0’。

如果 'width' 的计算值为 ‘auto’,则已使用值为 “收缩至适合” 宽度。

“收缩至适合” 宽度的计算方式类似于使用自动表格布局算法计算表格单元格宽度。大致步骤:先在不进行除显式换行符之外的换行的情况下格式化内容,得到首选宽度;再尝试所有可能的换行方式得到首选 最小 宽度。CSS 2.1 并未定义精确算法。随后求取 可用宽度:即包含块宽度减去已使用的 ‘margin-left’、‘border-left-width’、‘padding-left’、‘padding-right’、‘border-right-width’、‘margin-right’ 以及任何相关滚动条的宽度。

于是收缩至适合的宽度为:min( max(首选最小宽度, 可用宽度), 首选宽度)。

10.3.6 浮动,替换元素

如果 'margin-left''margin-right' 的计算值为 ‘auto’,其已使用值为 ‘0’。'width' 的已使用值按 行内替换元素 的方式确定。

10.3.7 绝对定位,非替换元素

在本节及下一节中,术语 “静态位置”(指元素)大致指元素在正常流中的位置。更精确地说:

但用户代理无需真正计算该假想盒子的尺寸,完全可以对其可能位置进行猜测。

在计算静态位置时,固定定位元素的包含块为初始包含块(而非视口),且所有可滚动盒子应假定已滚动至其原点。

决定这些元素已使用值的约束为

'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = 包含块的宽度

如果 ‘left’、‘width’ 与 ‘right’ 均为 ‘auto’:首先将任何 ‘auto’ 的 ‘margin-left’ 与 ‘margin-right’ 设为 0。随后,如果建立静态位置包含块的元素的 ‘direction’ 为 ‘ltr’,则将 ‘left’ 设为静态位置并使用下文第三条规则;否则将 ‘right’ 设为静态位置并使用下文第一条规则。

如果三者均不为 ‘auto’:若 ‘margin-left’ 与 ‘margin-right’ 均为 ‘auto’,则在满足等式的前提下令两外边距相等,除非这会导致负值;此时若包含块的方向为 ‘ltr’(‘rtl’),则把 ‘margin-left’(‘margin-right’)设为 0,并解算 ‘margin-right’(‘margin-left’)。若仅有 ‘margin-left’ 或 ‘margin-right’ 为 ‘auto’,则对该值求解。如果值约束过度,则在包含块的 ‘direction’ 为 ‘rtl’(‘ltr’)时忽略 ‘left’(‘right’)的值并求解该值。

否则,将 ‘margin-left’ 与 ‘margin-right’ 的 ‘auto’ 取值设为 0,并从以下六条规则中选取适用的一条:

  1. ‘left’ 与 ‘width’ 为 ‘auto’,且 ‘right’ 不是 ‘auto’,则宽度采用收缩至适合(shrink‑to‑fit),随后求解 ‘left’。
  2. 如果 ‘left’ 与 ‘right’ 为 ‘auto’,且 ‘width’ 不是 ‘auto’,则若建立静态位置包含块的元素的 ‘direction’ 为 ‘ltr’,则将 ‘left’ 设为静态位置;否则将 ‘right’ 设为静态位置。随后解算 ‘left’(若方向为 ‘rtl’)或 ‘right’(若方向为 ‘ltr’)。
  3. ‘width’ 与 ‘right’ 为 ‘auto’,且 ‘left’ 不是 ‘auto’,则宽度采用收缩至适合,然后求解 ‘right’。
  4. ‘left’ 为 ‘auto’,而 ‘width’ 与 ‘right’ 均不是 ‘auto’,则求解 ‘left’。
  5. ‘width’ 为 ‘auto’,而 ‘left’ 与 ‘right’ 均不是 ‘auto’,则求解 ‘width’。
  6. ‘right’ 为 ‘auto’,而 ‘left’ 与 ‘width’ 均不是 ‘auto’,则求解 ‘right’。

“收缩至适合” 宽度的计算方式同前文浮动元素的说明。大致步骤:首先求得首选宽度与首选最小宽度;随后求取 可用宽度——即在将 ‘left’(情形 1)或 ‘right’(情形 3)设为 0 后求解 ‘width’ 所得到的宽度。

于是收缩至适合的宽度为:min( max(首选最小宽度, 可用宽度), 首选宽度)。

10.3.8 绝对定位,替换元素

在此情形下,第 10.3.7 节的所有规则(包括约束方程)均适用,但其余部分被以下规则取代:

  1. ‘width’ 的已使用值按 行内替换元素 的方式确定。如果 'margin-left''margin-right' 被指定为 ‘auto’,其已使用值由下列规则决定。
  2. 如果 ‘left’ 与 ‘right’ 均为 ‘auto’,则若建立静态位置包含块的元素的 ‘direction’ 为 ‘ltr’,将 'left' 设为静态位置;若 ‘direction’ 为 ‘rtl’,则将 'right' 设为静态位置。
  3. 如果 ‘left’ 或 ‘right’ 为 ‘auto’,则将任何 ‘auto’ 的 ‘margin-left’ 或 ‘margin-right’ 替换为 ‘0’。
  4. 如果此时 ‘margin-left’ 与 ‘margin-right’ 仍为 ‘auto’,则在保证两外边距相等的前提下解算等式,除非会导致负值;此时若包含块的方向为 ‘ltr’(‘rtl’),则把 ‘margin-left’(‘margin-right’)设为 0 并求解 ‘margin-right’(‘margin-left’)。
  5. 如果此时仍有 ‘auto’ 的 ‘left’,则对该值求解。
  6. 如果此时值约束过度,则在包含块的 ‘direction’ 为 ‘rtl’ 时忽略 ‘left’,在 ‘direction’ 为 ‘ltr’ 时忽略 ‘right’,并对被忽略的值进行求解。

10.3.9 ‘inline-block’,非替换元素(正常流)

如果 ‘width’ 为 ‘auto’,则已使用值为收缩至适合宽度,和浮动元素相同。

'margin-left''margin-right' 的计算值为 ‘auto’,其已使用值为 ‘0’。

10.3.10 ‘inline-block’,替换元素(正常流)

完全同行内替换元素

10.4 最小与最大宽度'min-width''max-width'

'min-width'
  <length> | <percentage> | inherit
初始值  0
应用于  所有元素,但不包括非替换的行内元素、表行和行组
可继承  
百分比  参考包含块的宽度
媒体  视觉
计算值  按指定的百分比或绝对长度
'max-width'
  <length> | <percentage> | none | inherit
初始值  none(无)
应用于  所有元素,但不包括非替换的行内元素、表行和行组
可继承  
百分比  参考包含块的宽度
媒体  视觉
计算值  指定的百分比、绝对长度或 ‘none’

这两个属性允许作者将内容宽度约束在一定范围内。其取值含义如下:

<length>(长度)
指定一个固定的最小或最大已使用宽度。
<percentage>(百分比)
指定用于确定已使用值的百分比。百分比相对于生成盒子的包含块宽度计算。如果包含块宽度为负,则已使用值为 0。如果包含块宽度取决于该元素的宽度,则在 CSS 2.1 中布局未定义。
none(无)
(仅适用于 'max-width')盒子宽度无限制。

'min-width''max-width' 使用负值是非法的。

在 CSS 2.1 中,‘min-width’ 与 ‘max-width’ 对表格、行内表格、表格单元格、表格列以及列组的影响未定义。

以下算法描述了这两个属性如何影响 'width' 属性的已使用值

  1. 首先在不考虑 'min-width''max-width' 的情况下,依据上文 “计算宽度和外边距” 的规则计算暂定的已使用宽度。
  2. 如果暂定的已使用宽度大于 'max-width',则再次应用上述规则,但这一次使用 'max-width' 的计算值作为 'width' 的计算值。
  3. 如果得到的宽度小于 'min-width',则再次应用上述规则,不过这一次使用 'min-width' 的值作为 'width' 的计算值。

这些步骤并不影响上述属性的真实计算值。

然而,对于同时具有固有比例且 'width''height' 均为 ‘auto’ 的替换元素,算法如下:

从表格中选取相应约束冲突的已解析宽高值。将 max-widthmax-height 取为 max(min, max) 使得 minmax 成立。表中 wh 代表忽略 'min-width''min-height''max-width''max-height' 前的宽高计算结果。通常这些就是固有宽高,但对具有固有比例的替换元素可能不是。

注:如果显式设定了宽度或高度且另一维度为 auto,对 auto 侧施加最小或最大约束可能导致约束过度。规范明确了行为,但可能与作者的预期不符。可以使用 CSS3 的 object-fit 属性获得不同效果。

约束冲突已解析宽度已解析高度
none(无) w h
w > max-width max-width max(max-width * h/w, min-height)
w < min-width min-width min(min-width * h/w, max-height)
h > max-height max(max-height * w/h, min-width) max-height
h < min-height min(min-height * w/h, max-width) min-height
(w > max-width) 且 (h > max-height),且 (max-width/w ≤ max-height/h) max-width max(min-height, max-width * h/w)
(w > max-width) 且 (h > max-height),且 (max-width/w > max-height/h) max(min-width, max-height * w/h) max-height
(w < min-width) 且 (h < min-height),且 (min-width/w ≤ min-height/h) min(max-width, min-height * w/h) min-height
(w < min-width) 且 (h < min-height),且 (min-width/w > min-height/h) min-width min(max-height, min-width * h/w)
(w < min-width) 且 (h > max-height) min-width max-height
(w > max-width) 且 (h < min-height) max-width min-height

随后按 “计算宽度和外边距” 的规则处理,就好像 'width' 的计算值就是该值一样。

10.5 内容高度'height' 属性

'height'
  <length> | <percentage> | auto | inherit
初始值  auto
应用于  所有元素,但不包括非替换的行内元素、表列和列组
可继承  
百分比  参见正文
媒体  视觉
计算值  指定的百分比或 ‘auto’(见 <percentage>)或绝对长度

此属性指定盒子的内容高度

此属性不适用于非替换的行内元素。请参见非替换行内元素的高度与外边距计算章节以了解使用的规则。

值的含义如下:

<length>(长度)
使用长度值指定内容区域的高度。
<percentage>(百分比)
指定百分比高度。百分比相对于生成盒子的包含块高度计算。如果包含块的高度未显式指定(即取决于内容高度),且该元素不是绝对定位的,则该值计算为 ‘auto’。根元素的百分比高度相对于初始包含块 注:对于包含块基于块级元素的绝对定位元素,百分比相对于该元素的填充盒高度计算。这与 CSS1 不同,后者始终相对于父元素的内容盒高度计算。
auto
高度取决于其他属性的取值。见下文段落。

注意,绝对定位元素的包含块高度独立于元素本身的尺寸,因此此类元素的百分比高度总能解析。但有时需要等文档后面的元素处理完毕后才能得到高度。

'height'使用负值是非法的。

示例

例如,下面的规则将段落的内容高度设为 100 像素。

p { height: 100px }

当段落内容高度超过 100 像素时,将根据overflow属性以及'overflow'属性进行溢出处理

10.6 计算高度和外边距

在计算 'top''margin-top''height''margin-bottom''bottom' 的取值时,必须在各种盒子类型之间作区分。

  1. 行内,非替换元素
  2. 行内,替换元素
  3. 块级,非替换元素(正常流)
  4. 块级,替换元素(正常流)
  5. 浮动,非替换元素
  6. 浮动,替换元素
  7. 绝对定位,非替换元素
  8. 绝对定位,替换元素
  9. ‘inline-block’,非替换元素(正常流)
  10. ‘inline-block’,替换元素(正常流)

对于点 1‑6 与 9‑10,‘top’ 与 ‘bottom’ 的已使用值由第 9.4.3 节的规则决定。

注意:这些规则同样适用于根元素。

注意。 下面计算的 ‘height’ 已使用值是暂定值,可能需要多次计算,取决于'min-height''max-height',见下文 最小与最大高度 一节。

10.6.1 行内,非替换元素

'height' 属性不适用。内容区域的高度应基于字体,但本规范未规定具体方式。UA 可采用例如 em-box 或字体的最大上升部与下降部(后者可确保超出 em-box 的字形仍在内容区内,但会导致不同字体产生不同大小的盒子;前者可让作者相对于 ‘line-height’ 控制背景样式,但会出现字形绘制超出内容区的情况)。

注意:CSS 3 级别可能会加入属性以选择用于内容高度的字体度量方式。

行内、非替换盒子的垂直内边距、边框与外边距从内容区的顶部和底部开始,与'line-height' 无关。但仅在计算行盒子的高度时使用 'line-height'

如果使用了多种字体(例如出现了不同字体的字形),本规范没有定义内容区的高度。我们建议高度应足以容纳以下两者之一:

  1. 所有字体的 em-box;或
  2. 所有字体的最大上升部与下降部。
注意,这可能大于任何单一字体的字号,取决于字体的基线对齐方式。

10.6.2 行内替换元素、块级替换元素(正常流)、‘inline-block’ 替换元素(正常流)以及浮动替换元素

如果 'margin-top',或 'margin-bottom' 为 'auto',则它们的使用值为 0。

如果 'height''width' 均具有 'auto' 的计算值且元素还有固有高度,则该固有高度即为 'height' 的使用值。

否则,如果 'height' 的计算值为 'auto',且元素具有固有比例,则 'height' 的使用值为

(使用宽度) ÷ (固有比例)

否则,如果 'height' 的计算值为 'auto',且元素具有固有高度,则该固有高度即为 'height' 的使用值。

否则,如果 'height' 的计算值为 'auto',但上述条件均不满足,则必须将 'height' 的使用值设为满足以下条件的最大矩形的高度:比例为 2:1,高度不超过 150px,宽度不超过设备宽度。

10.6.3 块级非替换元素在普通流中,当 ‘overflow’ 计算为 ‘visible’ 时

本节同样适用于块级非替换元素在普通流中,当 ‘overflow’ 并未计算为 ‘visible’ 但已传播至视口时的情况。

如果 'margin-top',或 'margin-bottom' 为 'auto',则它们的使用值为 0。如果 'height' 为 'auto',则高度取决于元素是否有块级子元素以及是否具有内边距或边框。

元素的高度为从其顶部内容边缘到以下首次适用项之间的距离:

  1. 若盒子建立了包含一行或多行的行内格式上下文,则为最后一行盒子的底部边缘。
  2. 若其最后一个正常流子代的底部(可能已折叠的)外边距不与元素的底部外边距折叠,则为该子代的底部外边距底部边缘。
  3. 若其最后一个正常流子代的顶部外边距不与元素的底部外边距折叠,则为该子代的底部边框底部边缘。
  4. 否则为 0。

仅考虑普通流中的子元素(即忽略浮动框和绝对定位框,并且相对定位框在计算时不计其偏移)。请注意,子框可能是一个 匿名块框

10.6.4 绝对定位的非替换元素

在本节及下一节中,“静态位置”(元素的)大致指元素在普通流中原本所在的位置。更准确地说,‘top’ 的静态位置是指从包含块的顶部边缘到假想框的上外边缘的距离;该假想框是如果其指定的 'position' 为 ‘static’、'float' 为 ‘none’、'clear' 为 ‘none’ 时,此元素的第一个框。
(注意,根据 第 9.7 节 的规则,这可能还需假设 ‘display’ 的不同计算值。)如果假想框位于包含块之上,则该值为负。

但用户代理无需真正计算该假想盒子的尺寸,完全可以对其可能位置进行猜测。

在计算静态位置时,固定定位元素的包含块为初始包含块,而不是视口。

对于绝对定位元素,垂直尺寸的使用值必须满足以下约束:

'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = 包含块的高度

如果 ‘top’、‘height’ 与 ‘bottom’ 三者均为 auto,则将 ‘top’ 设为静态位置,并套用下面的第三条规则。

如果三者均不为 ‘auto’:若 ‘margin-top’ 与 ‘margin-bottom’ 均为 ‘auto’,在两个外边距相等的额外约束下求解方程。若 ‘margin-top’ 或 ‘margin-bottom’ 其中之一为 ‘auto’,则求解该外边距的值。若约束过多,则忽略 ‘bottom’ 的取值并求解 ‘bottom’ 的值。

否则,选取下列六条规则中适用的一条:

  1. ‘top’ 与 ‘height’ 为 auto,而 ‘bottom’ 不是 auto,则高度 依据内容(见 10.6.7),将 ‘margin-top’ 与 ‘margin-bottom’ 的 auto 值设为 0,并求解 ‘top’。
  2. ‘top’ 与 ‘bottom’ 为 auto,而 ‘height’ 不是 auto,则将 ‘top’ 设为静态位置,将 ‘margin-top’ 与 ‘margin-bottom’ 的 auto 值设为 0,并求解 ‘bottom’。
  3. ‘height’ 与 ‘bottom’ 为 auto,而 ‘top’ 不是 auto,则高度 依据内容(见 10.6.7),将 ‘margin-top’ 与 ‘margin-bottom’ 的 auto 值设为 0,并求解 ‘bottom’。
  4. ‘top’ 为 ‘auto’,而 ‘height’ 与 ‘bottom’ 均不是 ‘auto’,则将 ‘margin-top’ 与 ‘margin-bottom’ 的 ‘auto’ 取值设为 0,并求解 ‘top’。
  5. ‘height’ 为 ‘auto’,而 ‘top’ 与 ‘bottom’ 均不是 ‘auto’,则将 ‘margin-top’ 与 ‘margin-bottom’ 的 ‘auto’ 取值设为 0,并求解 ‘height’。
  6. ‘bottom’ 为 ‘auto’,而 ‘top’ 与 ‘height’ 均不是 ‘auto’,则将 ‘margin-top’ 与 ‘margin-bottom’ 的 ‘auto’ 取值设为 0,并求解 ‘bottom’。

10.6.5 绝对定位的替换元素

此情况类似于前一种,只是元素具有 固有 高度。替换顺序现在为:

  1. ‘height’ 的使用值按 行内替换元素 的规则确定。如果 ‘margin-top’ 或 ‘margin-bottom’ 被指定为 ‘auto’,则其使用值按下列规则决定。
  2. 如果 ‘top’ 与 ‘bottom’ 均为 ‘auto’,则用元素的 静态位置 替代 ‘top’。
  3. 如果 ‘bottom’ 为 ‘auto’,则把 ‘margin-top’ 或 ‘margin-bottom’ 上的任何 ‘auto’ 替换为 ‘0’。
  4. 此时如果 ‘margin-top’ 与 ‘margin-bottom’ 仍为 ‘auto’,则在额外约束 “两个外边距必须相等” 下求解方程。
  5. 此时如果只剩下一个 ‘auto’,则为该值求解方程。
  6. 此时如果数值约束过多,则忽略 ‘bottom’ 的值并求解该值。

10.6.6 复杂情况

本节适用于

如果 'margin-top',或 'margin-bottom' 为 'auto',则它们的使用值为 0。如果 'height' 为 'auto',则 高度取决于元素的后代(见 10.6.7)

对于 ‘inline-block’ 元素,在计算行盒的高度时使用外边距框。

10.6.7 块格式化上下文根元素的 ‘auto’ 高度

在某些情况下(参见例如第 10.6.4 节和第 10.6.6 节),建立块格式化上下文的元素的高度按以下方式计算:

如果仅有内联子元素,则高度为最上面行盒的顶部与最下面行盒的底部之间的距离。

如果它拥有块级子元素,则高度为最顶部块级子框的上外边缘到最底部块级子框的下外边缘之间的距离。

绝对定位的子元素被忽略;相对定位的盒子在计算时不计其偏移。请注意,子框可能是一个 匿名块框

另外,如果元素的任何浮动后代的下外边缘位于元素的内容底部之外,则高度会扩大以包含这些外边缘。仅考虑参与此块格式化上下文的浮动,例如位于绝对定位后代或其他浮动内部的浮动不计入。

10.7 最小和最大高度'min-height''max-height'

有时需要将元素的高度限制在一定范围内。两条属性提供了此功能。

'min-height'
  <length> | <percentage> | inherit
初始值  0
应用于  所有元素,但不包括非替换的行内元素、表列和列组
可继承  
百分比  参见正文
媒体  视觉
计算值  按指定的百分比或绝对长度
'max-height'
  <length> | <percentage> | none | inherit
初始值  none(无)
应用于  所有元素,但不包括非替换的行内元素、表列和列组
可继承  
百分比  参见正文
媒体  视觉
计算值  指定的百分比、绝对长度或 ‘none’

这两个属性允许作者将盒子的高度限制在一定范围内。取值含义如下:

<length>(长度)
指定一个固定的最小或最大 **计算** 高度。
<percentage>(百分比)
指定一个百分比,用于确定使用值。该百分比相对于生成框的 包含块 的高度计算。如果包含块的高度未明确指定(即取决于内容高度),且该元素不是绝对定位的,则该百分比值在 'min-height' 情况下视为 ‘0’,在 'max-height' 情况下视为 ‘none’。
none(无)
(仅对 'max-height')没有对盒子高度的限制。

'min-height''max-height' 指定负值是非法的。

在 CSS 2.1 中,‘min-height’ 与 ‘max-height’ 对表格、行内表格、单元格、行以及行组的影响未定义。

下面的算法描述了这两个属性如何影响 使用值'height' 属性。

  1. 首先计算暂定使用高度(不考虑 'min-height''max-height'),按照上文 “计算高度和外边距” 中的规则进行。
  2. 如果该暂定高度大于 'max-height',则再次套用上述规则,但这次使用 'max-height' 的值作为 'height' 的计算值。
  3. 如果得到的高度小于 'min-height',则再次套用上述规则,但这次使用 'min-height' 的值作为 'height' 的计算值。

这些步骤不会影响上述属性的真实计算值。使用值的改变仅在 'min-height''max-height' 规则(见 “外边距合并”(8.3.1))明确要求时,对外边距合并产生影响。

然而,对于宽度和高度均计算为 ‘auto’ 的替换元素,使用 上文“最小和最大宽度” 的算法先求出使用宽度和高度。随后,按 “计算高度和外边距” 中的规则,使用得到的宽度和高度视为计算值再次进行处理。

10.8 行高计算'line-height''vertical-align' 属性

行内格式化上下文 小节所述,用户代理将行内盒子流入一个垂直堆叠的 行盒。行盒的高度按如下方式确定:

  1. 先计算行盒中每个行内盒子的高度。对于替换元素、inline‑block 元素以及 inline‑table 元素,这指的是它们的外边距框高度;对于普通行内盒子,则是它们的 ‘line-height’(参见 “计算高度和外边距”行内盒高度 中的 “行距和半行距”)。
  2. 随后根据各行内盒子的 'vertical-align' 属性进行垂直对齐。如果它们被对齐为 ‘top’ 或 ‘bottom’,则必须对齐以最小化行盒高度。若此类盒子足够高,可能出现多种解,CSS 2.1 并未定义行盒基线的位置(即 基准线(见下文) 的位置)。
  3. 行盒的高度是最上方盒子顶部与最下方盒子底部之间的距离。(这包括 基准线,如下面 'line-height' 所述。)

空的行内元素会生成空的行内盒子,但这些盒子仍拥有外边距、内边距、边框和行高,因此在计算时同样会产生影响,正如包含内容的元素一样。

10.8.1 行距与半行距

CSS 假设每种字体都有度量指标,指明基线以上的特征高度和基线以下的深度。在本节中我们用 A 表示该高度(针对特定字号的特定字体),用 D 表示深度。我们还定义 AD = A + D,即从顶部到底部的距离。(下文关于 TrueType 与 OpenType 字体中如何获取 AD 的说明)请注意,这些是整个字体的度量,并不一定对应任意单个字形的上升线与下降线。

用户代理必须按照各自的基线将非替换行内盒中的字形对齐。随后,对每个字形分别确定其 AD。注意,同一元素内的字形可能来自不同字体,从而它们的 AD 并不一定相同。如果该行内盒子根本不包含字形,则视为包含一个 基准线(宽度为零的不可见字形),其 AD 取自元素的首个可用字体。

仍然针对每个字形,计算需要添加的行距 L,其中 L = 'line-height' - AD。将一半的行距加在 A 之上,另一半加在 D 之下,使得字形连同行距的总上高度为 A' = A + L/2,总下深度为 D' = D + L/2。

注释。 L 可以为负值。

行内盒的高度包含所有字形及其两侧的半行距,正好等于 ‘line-height’。子元素的盒子不影响此高度。

虽然非替换元素的外边距、边框和内边距不参与行盒的高度计算,但它们仍然会在行内盒周围渲染。这意味着如果 'line-height' 指定的高度小于所含盒子的内容高度,背景、内边距和边框的颜色可能会“泄露”到相邻的行盒中。用户代理应按文档顺序渲染这些盒子,这会导致后续行的边框覆盖前面行的边框和文字。

注释。 CSS 2.1 未定义行内盒的内容区域是什么(参见上文 10.6.1),因此不同的 UA 可能在不同位置绘制背景和边框。

注释。 建议使用 OpenType 或 TrueType 字体的实现,从字体的 OS/2 表中读取指标 “sTypoAscender” 与 “sTypoDescender” 作为 A 与 D(随后按当前元素的字体大小进行缩放)。若缺少这些指标,则应使用 HHEA 表中的 “Ascent” 与 “Descent”。

'line-height'
  normal | <number> | <length> | <percentage> | inherit
初始值  normal
应用于  所有元素
可继承  
百分比  指元素本身的字体大小
媒体  视觉
计算值  对于 <length><percentage>,取其绝对值;否则按规定使用。

在内容由 行内级别 元素组成的 块容器元素上,‘line-height’ 指定该元素内部行盒的 最小 高度。最小高度包括基线以上的最小上高度和基线以下的最小深度,等同于每个行盒都从 宽度为零、使用元素字体和行高属性的基准线盒子 开始。我们将此虚构盒子称为 “基准线(strut)”。(此名称来源于 TeX。)

字体在基线上下的高度与深度被视为已内嵌在字体内部的度量值。(欲了解更多细节,请参见 CSS 3 级。)

在非替换的 行内 元素上,‘line-height’ 指定用于计算行盒高度的值。

此属性的值具有以下含义

normal
指示用户代理将使用值设为基于元素字体的 “合理” 值。其含义同 <number>。我们建议 ‘normal’ 的使用值介于 1.0 到 1.2 之间。其 计算值 为 ‘normal’。
<length>(长度)
指定的长度用于计算行盒高度。负值为非法。
<number>(数字)
属性的使用值为该数字乘以元素的字体大小。负值为非法。其 计算值 与指定值相同。
<percentage>(百分比)
属性的计算值为该百分比乘以元素的已计算字体大小。负值为非法。

示例

下面示例中的三条规则会产生相同的实际行高。

div { line-height: 1.2; font-size: 10pt }     /* number */
div { line-height: 1.2em; font-size: 10pt }   /* length */
div { line-height: 120%; font-size: 10pt }    /* percentage */

当元素包含的文本使用了多种字体时,用户代理可根据最大字体尺寸确定 ‘normal’ 的 'line-height' 值。

注释。 当块容器盒中所有行内盒的 ‘line-height’ 只有一种数值且全部使用相同字体(且不存在替换元素、inline‑block 元素等)时,上述规则可确保相邻行的基线间距正好等于 'line-height',这在不同字体的文本列需要对齐(例如表格中)时尤为重要。

'vertical-align'
  baseline | sub | super | top | text-top | middle | bottom | text-bottom | <percentage> | <length> | inherit
初始值  baseline
应用于  行内级别和 ‘table-cell’ 元素
可继承  
百分比  参考元素自身的“line-height”
媒体  视觉
计算值  对于 <percentage><length>,取其绝对长度;否则按规定使用。

此属性影响行盒内由行内级元素生成的盒子的垂直定位。

注释。 此属性的取值在表格上下文中意义不同。请参阅 表格高度算法 小节获取详情。

下列取值仅在相对于父行内元素或相对于父块容器元素的 基准线 时才有意义。

在以下定义中,对于行内非替换元素,用于对齐的盒子是高度等于 ‘line-height’ 的盒子(包含该盒子的字形及其两侧的半行距,参见上文 行内盒高度)。对于所有其他元素,用于对齐的盒子为外边距框。

baseline
将盒子的基线与父盒子的基线对齐。如果该盒子没有基线,则将其下外边缘与父元素的基线对齐。
middle
将框的垂直中点与父框的基线加上父框 x 高度的一半对齐。
sub (下标)
将框的基线降低到父框下标的适当位置。(此值对元素文本的字号没有影响。)
super (上标)
将框的基线升高到父框上标的适当位置。(此值对元素文本的字号没有影响。)
text-top
将盒子的顶部与父元素内容区的顶部对齐(参见 10.6.1)。
text-bottom
将盒子的底部与父元素内容区的底部对齐(参见 10.6.1)。
<percentage>(百分比)
将盒子向上(正值)或向下(负值)移动此距离(该距离为 'line-height' 的百分比)。值 ‘0%’ 等同于 ‘baseline’。
<length>(长度)
将盒子向上(正值)或向下(负值)移动此距离。值 ‘0cm’ 等同于 ‘baseline’。

以下取值使元素相对于行盒对齐。由于元素可能有相对于它对齐的子元素(这些子元素的后代又可能相对于它们对齐),这些取值使用对齐子树的边界。对齐子树 指的是该行内元素本身以及所有计算后的 ‘vertical-align’ 值不是 ‘top’ 或 ‘bottom’ 的子行内元素的对齐子树。对齐子树的顶部是子树中所有盒子顶部的最高者,底部则同理。

top
将对齐子树的顶部与行盒的顶部对齐。
bottom
将对齐子树的底部与行盒的底部对齐。

‘inline-table’ 的基线是该表格第一行的基线。

‘inline-block’ 的基线是其在正常流中最后一行盒子的基线,除非它没有流内行盒子,或其 'overflow' 属性的计算值不是 'visible',在这种情况下基线是底部外边距边缘。