8 盒模型

内容

CSS 盒模型描述了为文档树中的元素生成的矩形框,并根据视觉格式模型进行布局。

8.1 盒子尺寸

每个盒子都有一个 内容区域(例如文本、图像等)以及可选的周围 内边距 边框 外边距区域;每个区域的大小由下面定义的属性指定。下图显示了这些区域的关系及其引用的术语:

说明内容、内边距、边框和外边距之间关系的图像。   [D]

外边距、边框和内边距可以分解为顶部、右侧、底部和左侧部分(例如,在图中,"LM"表示左外边距,"RP"表示右内边距,"TB"表示顶部边框等)。

每个区域的周长称为“边缘”,因此每个盒子有四个边缘:

内容边缘内边缘
内容边缘围绕由盒子的宽度高度 给定的矩形,通常取决于元素的渲染内容。 四个内容边缘定义了盒子的 内容盒
内边距边缘
内边距边缘围绕盒子的内边距。如果内边距的宽度为0,则内边距边缘与内容边缘相同。 四个内边距边缘定义了盒子的 内边距盒
边框边缘
边框边缘围绕盒子的边框。如果边框的宽度为0,则边框边缘与内边距边缘相同。 四个边框边缘定义了盒子的 边框盒
外边距边缘外边缘
外边距边缘围绕盒子的外边距。如果外边距的宽度为0,则外边距边缘与边框边缘相同。 四个外边距边缘定义了盒子的 外边距盒

每个边缘可分为顶部、右侧、底部和左侧边缘。

盒子内容区域的尺寸— 内容宽度内容高度— 取决于多个因素:生成盒子的元素是否设置了'宽度''高度'属性, 盒子是否包含文本或其他盒子,盒子是否为表格等。盒子宽度和高度的相关内容在可视化格式模型细节一章中进行了讨论。

盒子的内容、内边距和边框区域的背景样式由生成元素的'背景'属性指定。外边距背景始终为透明。

8.2 外边距、内边距和边框的示例

此示例说明了外边距、内边距和边框如何交互。示例HTML文档:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>外边距、内边距和边框的示例</TITLE>
    <STYLE type="text/css">
      UL { 
        background: yellow; 
        margin: 12px 12px 12px 12px;
        padding: 3px 3px 3px 3px;
                                     /* 未设置边框 */
      }
      LI { 
        color: white;                /* 文本颜色为白色 */ 
        background: blue;            /* 内容和内边距将为蓝色 */
        margin: 12px 12px 12px 12px;
        padding: 12px 0px 12px 12px; /* 注意右内边距为0px */
        list-style: none             /* 列表项前无符号 */
                                     /* 未设置边框 */
      }
      LI.withborder {
        border-style: dashed;
        border-width: medium;        /* 设置所有边的边框宽度 */
        border-color: lime;
      }
    </STYLE>
  </HEAD>
  <BODY>
    <UL>
      <LI>列表的第一个元素
      <LI class="withborder">列表的第二个元素稍长一些,以说明换行情况。
    </UL>
  </BODY>
</HTML>

生成的文档树中(以及其他关系中)包含一个UL元素,它有两个LI子元素。

以下第一个图说明了此示例会生成什么。第二个图说明了UL元素的外边距、内边距和边框与其子元素LI的关系。(图像未按比例绘制。)

说明父元素和子元素之间的外边距、边框和内边距关系的图像。   [D]

注意:

8.3 外边距属性'margin-top''margin-right''margin-bottom''margin-left'、 和 'margin'

外边距属性指定了盒子的外边距区域的宽度。'margin'速记属性 设置所有四个边的外边距,而其他外边距属性只设置它们各自的边。这些属性适用于所有元素,但垂直外边距对非替换的内联元素不起作用。

本节定义的属性涉及<margin-width> 值类型,可以取以下值之一:

<长度>
指定固定宽度。
<百分比>
百分比是相对于生成的盒子的宽度来计算的 包含块请注意,这对'margin-top''margin-bottom'也是如此。 如果包含块的宽度取决于此元素,则在CSS 2.2中结果布局未定义。
auto
有关行为,请参见计算宽度和外边距部分。

外边距属性允许负值,但可能存在特定实现的限制。

名称: margin-topmargin-bottom
值: <margin-width> | inherit
初始值: 0
适用于: 除表格显示类型为 table-caption、table 和 inline-table 以外的所有元素
继承:
百分比: 相对于包含块的宽度
媒体: 视觉
计算值: 指定的百分比或绝对长度

这些属性对非替换的内联元素无效。

名称: margin-rightmargin-left
值: <margin-width> | inherit
初始值: 0
适用于: 除表格显示类型为 table-caption、table 和 inline-table 以外的所有元素
继承:
百分比: 相对于包含块的宽度
媒体: 视觉
计算值: 指定的百分比或绝对长度

这些属性设置盒子的上、右、下和左外边距。

示例:

h1 { margin-top: 2em }
名称: margin
值: <margin-width>{1,4} | inherit
初始值: 见各个属性
适用于: 除表格显示类型为 table-caption、table 和 inline-table 以外的所有元素
继承:
百分比: 相对于包含块的宽度
媒体: 视觉
计算值: 见各个属性

'margin'属性是 设置'margin-top''margin-right''margin-bottom''margin-left'的速记属性,在样式表中设置它们的位置。

如果只有一个组件值,它适用于所有边。如果有两个值,则将第一个值设置为上、下边距,将第二个值设置为左、右边距。如果有三个值,第一个值设置为上边距,第二个值设置为左、右边距,第三个值设置为下边距。如果有四个值,则分别应用于上、右、下和左边。

示例:

body { margin: 2em }         /* 所有外边距设置为 2em */
body { margin: 1em 2em }     /* 上下 = 1em,左右 = 2em */
body { margin: 1em 2em 3em } /* 上=1em,右=2em,下=3em,左=2em */

上面示例中的最后一条规则等效于下面的示例:

body {
  margin-top: 1em;
  margin-right: 2em;
  margin-bottom: 3em;
  margin-left: 2em;        /* 从相对的边复制过来(右边) */
}

8.3.1 折叠外边距

在 CSS 中,两个或多个盒子的相邻外边距(可能是兄弟元素,也可能不是)可以组合成一个外边距。以这种方式组合的外边距称为折叠,生成的组合外边距称为折叠外边距

相邻的垂直外边距会折叠,除非:

水平外边距永远不会折叠。

只有在以下情况下,两个外边距才是相邻的:

如果任何组件外边距与另一个外边距相邻,则折叠的外边距也被认为是与该外边距相邻的。

注意: 相邻的外边距可以由不是兄弟或祖先关系的元素生成。

注意 上述规则意味着:

当两个或多个外边距折叠时,结果的外边距宽度是折叠外边距宽度中的最大值。在负外边距的情况下,负相邻外边距的绝对值的最大值从正相邻外边距的最大值中扣除。如果没有正外边距,则从零中扣除相邻外边距的绝对值的最大值。

如果盒子的上下外边距相邻,则可能会通过它折叠。在这种情况下,该元素的位置取决于其与折叠外边距的其他元素的关系。

请注意,通过折叠的元素的位置不会影响与其折叠的其他元素的位置;顶部边框边缘的位置仅用于布局这些元素的后代。

8.4 填充属性: 'padding-top', 'padding-right', 'padding-bottom', 'padding-left', 和 'padding'

填充属性指定盒子填充区域的宽度。'padding'简写属性设置四个边的填充,而其他填充属性只设置相应的边。

本节定义的属性涉及到<padding-width>值类型,该值可以是以下之一:

<length>
指定一个固定宽度。
<percentage>
百分比相对于生成的盒子的包含块宽度进行计算,即使是'padding-top''padding-bottom'。 如果包含块的宽度依赖于此元素,则在 CSS 2.2 中的布局结果是未定义的。

与边距属性不同,填充值不能为负值。与边距属性类似,填充属性的百分比值是相对于生成的盒子的包含块的宽度计算的。

名称: padding-top, padding-right, padding-bottom, padding-left
值: <padding-width> | inherit
初始值: 0
适用于: 除表格行组、表格头组、表格尾组、表格行、表格列组和表格列之外的所有元素
继承:
百分比: 参考包含块的宽度
媒体: 视觉
计算值: 指定的百分比或绝对长度

这些属性设置盒子的顶部、右侧、底部和左侧填充。

示例(s):

blockquote { padding-top: 0.3em }
名称: padding
值: <padding-width>{1,4} | inherit
初始值: 见各个属性
适用于: 除表格行组、表格头组、表格尾组、表格行、表格列组和表格列之外的所有元素
继承:
百分比: 参考包含块的宽度
媒体: 视觉
计算值: 见各个属性

'padding'属性是'padding-top''padding-right''padding-bottom''padding-left'的简写属性,在样式表中同时设置这些属性。

如果只有一个组件值,则该值适用于所有边。如果有两个值,则顶部和底部填充设置为第一个值,右侧和左侧填充设置为第二个值。如果有三个值,则顶部设置为第一个值,左侧和右侧设置为第二个值,底部设置为第三个值。如果有四个值,则它们分别适用于顶部、右侧、底部和左侧。

填充区域的表面颜色或图像通过'background'属性指定:

示例(s):

h1 { 
  background: white; 
  padding: 1em 2em;
} 

上述示例指定了 '1em' 的垂直填充('padding-top''padding-bottom') 和 '2em' 的水平填充 ('padding-right''padding-left')。'em' 单位是相对的,相对于元素的字体大小: '1em' 等于使用的字体大小。

8.5 边框属性

边框属性指定盒子的边框区域的宽度、颜色和样式。这些属性适用于所有元素。

注意: 特别是在HTML中,用户代理可能会为某些用户界面元素(例如按钮、菜单等)渲染边框,这些边框可能与“普通”元素的渲染方式不同。

8.5.1 边框宽度: 'border-top-width', 'border-right-width', 'border-bottom-width', 'border-left-width', 和 'border-width'

边框宽度属性指定边框区域的宽度。本节定义的属性涉及到<border-width>值类型,该值可以是以下之一:

thin
一个窄边框。
medium
一个中等边框。
thick
一个厚边框。
<length>
边框的厚度具有明确的值。明确的边框宽度不能为负。

前三个值的解释取决于用户代理。但是,以下关系必须成立:

'thin' <='medium' <= 'thick'。

此外,这些宽度在整个文档中必须保持不变。

名称: border-top-width, border-right-width, border-bottom-width, border-left-width
值: <border-width> | inherit
初始值: medium
适用于: 所有元素
继承:
百分比: N/A
媒体: 视觉
计算值: 绝对长度;如果边框样式是 'none' 或 'hidden',则为 '0'

这些属性设置盒子的顶部、右侧、底部和左侧边框的宽度。

名称: border-width
值: <border-width>{1,4} | inherit
初始值: 见各个属性
适用于: 所有元素
继承:
百分比: N/A
媒体: 视觉
计算值: 见各个属性

该属性是'border-top-width''border-right-width''border-bottom-width''border-left-width' 的简写属性,在样式表中同时设置这些属性。

如果只有一个组件值,它适用于所有边。如果有两个值,则顶部和底部边框设置为第一个值,右侧和左侧设置为第二个值。如果有三个值,则顶部设置为第一个值,左侧和右侧设置为第二个值,底部设置为第三个值。如果有四个值,则它们分别适用于顶部、右侧、底部和左侧。

示例(s):

在下面的示例中,注释指示了顶部、右侧、底部和左侧边框的宽度:

h1 { border-width: thin }                   /* thin thin thin thin */
h1 { border-width: thin thick }             /* thin thick thin thick */
h1 { border-width: thin thick medium }      /* thin thick medium thick */

8.5.2 边框颜色: 'border-top-color', 'border-right-color', 'border-bottom-color', 'border-left-color', 和 'border-color'

边框颜色属性指定盒子边框的颜色。

名称: border-top-color, border-right-color, border-bottom-color, border-left-color
值: <color> | transparent | inherit
初始值: ‘color’属性的值
适用于: 所有元素
继承:
百分比: N/A
媒体: 视觉
计算值: 当取自‘color’属性时,使用‘color’的计算值;否则,按指定值计算
名称: border-color
值: [ <color> | transparent ]{1,4} | inherit
初始值: 见各个属性
适用于: 所有元素
继承:
百分比: N/A
媒体: 视觉
计算值: 见各个属性

'border-color'属性设置四个边框的颜色。值的含义如下:

<color>
指定颜色值。
transparent
边框是透明的(尽管它可能有宽度)。

'border-color'属性可以包含一到四个组件值,这些值的设置方式与'border-width'相同。

如果元素的边框颜色没有通过边框属性指定,用户代理必须使用元素的'color'属性值作为边框颜色的计算值

示例(s):

在这个例子中,边框将是一个实心的黑色线条。

p { 
  color: black; 
  background: white; 
  border: solid;
}

8.5.3 边框样式: 'border-top-style', 'border-right-style', 'border-bottom-style', 'border-left-style', 和 'border-style'

边框样式属性指定盒子的边框线条样式(实线、双线、虚线等)。本节定义的属性引用了 <border-style> 值类型,该值可以取以下几种值:

none
没有边框;计算的边框宽度为零。
hidden
与‘none’相同,但在边框冲突解决中针对表格元素有不同的处理。
dotted
边框为一系列点。
dashed
边框为一系列短线段。
solid
边框为一条单线段。
double
边框为两条实线。两条线及其间距之和等于'border-width'的值。
groove
边框看起来像是刻入画布中的。
ridge
‘groove’的反义:边框看起来像是从画布中凸出来的。
inset
边框使盒子看起来像是嵌入到画布中的。
outset
‘inset’的反义:边框使盒子看起来像是从画布中凸出来的。

所有边框都绘制在盒子的背景上。‘groove’、‘ridge’、‘inset’和‘outset’值的边框颜色取决于元素的边框颜色属性,但UA可以选择自己的算法来计算实际使用的颜色。例如,如果‘border-color’的值是‘silver’,那么UA可以使用从白色到深灰色的渐变颜色来表示倾斜的边框。

名称: border-top-style, border-right-style, border-bottom-style, border-left-style
值: <border-style> | inherit
初始值: none
适用于: 所有元素
继承:
百分比: N/A
媒体: 视觉
计算值: 按指定值
名称: border-style
值: <border-style>{1,4} | inherit
初始值: 见各个属性
适用于: 所有元素
继承:
百分比: N/A
媒体: 视觉
计算值: 见各个属性

'border-style' 属性设置四个边框的样式。它可以有一个到四个组件值,并且这些值的设置方式与上面的'border-width'相同。

示例(s):

#xy34 { border-style: solid dotted }

在上面的例子中,水平边框将是‘实线’,垂直边框将是‘虚线’。

由于边框样式的初始值是‘none’,除非设置了边框样式,否则边框将不可见。

8.5.4 边框简写属性: 'border-top', 'border-right', 'border-bottom', 'border-left', 和 'border'

名称: border-top, border-right, border-bottom, border-left
值: [ <border-width> || <border-style> || <'border-top-color'> ] | inherit
初始值: 见各个属性
适用于: 所有元素
继承:
百分比: N/A
媒体: 视觉
计算值: 见各个属性

这是一个用于同时设置盒子顶部、右侧、底部和左侧边框的宽度、样式和颜色的简写属性。

示例(s):

h1 { border-bottom: thick solid red }

上述规则将设置H1元素下方边框的宽度、样式和颜色。如果省略某个值,则该值将设置为它的初始值。由于以下规则没有指定边框颜色,因此边框将具有'color'属性指定的颜色:

H1 { border-bottom: thick solid }
名称: border
值: [ <border-width> || <border-style> || <'border-top-color'> ] | inherit
初始值: 见各个属性
适用于: 所有元素
继承:
百分比: N/A
媒体: 视觉
计算值: 见各个属性

'border' 属性是一个简写属性,用于同时设置盒子的四个边框的相同宽度、颜色和样式。与'margin''padding'简写属性不同,'border'属性无法为四个边框设置不同的值。要实现不同的值,必须使用其他边框属性。

示例(s):

例如,下面的第一个规则等价于后面显示的一组四个规则:

p { border: solid red }
p {
  border-top: solid red;
  border-right: solid red;
  border-bottom: solid red;
  border-left: solid red
}

由于这些属性在一定程度上具有重叠的功能,因此指定规则的顺序很重要。

示例(s):

请考虑此示例:

blockquote {
  border: solid red;
  border-left: double;
  color: black;
}

在上面的示例中,左边框的颜色为黑色,而其他边框为红色。这是因为'border-left'设置了宽度、样式和颜色。由于'border-left'属性未指定颜色值,因此将从'color'属性中获取颜色值。'color'属性是在'border-left'属性之后设置的,这一点并不重要。

8.6 双向上下文中内联元素的盒模型

对于每个行框,UA必须按照视觉顺序(而不是逻辑顺序)渲染为每个元素生成的内联框的边距、边框和填充。

当元素的'direction'属性为'ltr'时,第一个行框中生成的最左边的框具有左边距、左边框和左填充,最后一个行框中生成的最右边的框具有右填充、右边框和右边距。

当元素的'direction'属性为'rtl'时,第一个行框中生成的最右边的框具有右填充、右边框和右边距,最后一个行框中生成的最左边的框具有左边距、左边框和左填充。