Blog A Paranoid Guy

W3C之CSS标准 'Box model' 译注


译者注: 为了更详细了解 W3C CSS标准 的细节,于是试着读了 W3C CSS标准 的第8章 Box model。全是英文啊(。﹏。),本身英文水平就不高,借助了翻译工具一边翻译一边理解。最后,试着全章翻译记录一下吧。注:文章翻译有个人理解,稍有偏差和瑕疵哦

8 盒模型

8.1 盒尺寸

每一个盒子有一个内容区域(例如,文本,图像等)和可选的周边填充,边界和边缘区域,每个区域的大小是由下面的属性定义。下面的图展示了边缘、边框和填充这些区域的关系:

外边距,边框,和内边距可以细分为上,右,下,左几部分(比如,在上图中,LM 指的是左外边距,RP 指右内边距,TB 指上边框等)。

每个部分的边界(内容,内边距,边框,外边距)称之为 边缘,所以每个盒子都有四个边缘:

  • 内容边缘或内边缘

内容边缘由内容的宽度高度撑起,通常取决于元素的渲染内容大小。它的四个边缘定义了盒子的内容

  • 内边距边缘

内边距边缘紧靠着盒子的内边距外面。如果内边距为 0,内边距边缘就是内容边缘。它的四个边缘定义了盒子的内边距

  • 边框边缘

边框边缘紧靠着盒子的边框。如果边框宽度为 0,边框边缘就是内边距边缘。它的四个边缘定义了盒子的边框

  • 外边距边缘或内边缘

外边距边缘紧靠着外边距。如果外边距为 0,外边距边缘就是边框边缘。它的四个边缘定义了盒子的外边距

每个边缘都可以细分为上,下,左,右几部分

盒子内容区域的尺寸——内容的宽度和高度,通常取决与几个因素:盒子元素是否设置了的属性,盒子里面是否包含文本或其它盒子,这个盒子是不是表格等。关于盒子的宽和高的描述详见可视化格式模型部分


8.2 外边距,外边距和边框的例子

这个例子说明了边缘、填充和边框的关系。这是一个 HTML 文档:

  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
  <html>
    <head>
      <title>Examples of margins, padding, and borders</title>
      <style type="text/css">
        ul { 
          background: yellow; 
          margin: 12px 12px 12px 12px;
          padding: 3px 3px 3px 3px;
                                       /* No borders set */
        }
        li { 
          color: white;                /* text color is white */ 
          background: blue;            /* Content, padding will be blue */
          margin: 12px 12px 12px 12px;
          padding: 12px 0px 12px 12px; /* Note 0px padding right */
          list-style: none             /* no glyphs before a list item */
                                       /* No borders set */
        }
        li.withborder {
          border-style: dashed;
          border-width: medium;        /* sets border width on all sides */
          border-color: lime;
        }
      </style>
    </head>
    <body>
      <ul>
        <li>First element of list</li>
        <li class="withborder">Second element of list is
             a bit longer to illustrate wrapping.</li>
      </ul>
    </body>
  </html>

节点树里有一个 ul 元素包含这两个 li 元素

第一个图首先说明了这个例子将产生什么。第二个图展示了 ul 元素的外边距,内边距和边框还有 li 元素的空间关系

注意:

  • 每个 li 盒子的内容宽度计算自上而下;每个 li 盒子的包含块都是由 ul 元素创建

  • 每个 li 盒子的高度取决于内容高度加上顶部和底部的填充,边框宽度还有外边距。注意两个 li 盒子垂直方向上的折叠

  • li 盒子的右填充被设为 0。第二幅图明显可以看出来

  • li 盒子的外边距是透明的——外边距总是透明的——所以可以透过看到 ul 的黄色的背景色

  • 第二个 li 节点指定了一个虚线边框(border-style属性)

8.3 外边距属性:margin-top, margin-right, margin-bottom, margin-left, margin

外边距属性指定了一个盒子外部区域的宽度。margin属性可以指定为上右下左四个值。这个属性适用于所有元素,但垂直边缘不会对未替换的内联元素产生任何影响

本节定义的 <margin-width> 值类型,它可以是以下几个值:

  • 长度

指定的固定宽度

  • 百分比

按照百分比指定包含块的宽度

  • auto(自动)

auto 的计算详见 calculating widths and margins

允许的边值属性的负值,但可能指定特定的范围

margin-top, margin-bottom :

值:<margin-width> | 继承

初始值: 0

适用于:所有元素,除表格标题、表格和内联表格外

继承:no

百分比: 取决于包含块的宽度

媒体查询: visual

计算值: 指定的值或百分比

这些属性对非替换内联元素有没有影响

margin-right, margin-left :

值:<margin-width> | 继承

初始值: 0

适用于:所有元素,除表格标题、表格和内联表格外

继承:no

百分比: 取决于包含块的宽度

媒体查询: visual

计算值: 指定的值或百分比

这些属性设置了盒子的顶部,右边,底部和左边的外边距

  h1 {margin-top: 2em}

margin :

值:<margin-width>{1到4个值} | 继承

初始值: 参见上述属性的值

适用于:所有元素,除表格标题、表格和内联表格外

继承:no

百分比: 取决于包含块的宽度

媒体查询: visual

计算值: 参见上述属性的值

margin 属性比起来同时设置 margin-top, margin-right, margin-bottom, margin-left 更为简洁,但样式是一模一样的

如果 margin 只有一个值,它设置所有的四个属性;如果有两个值,则顶部和底部被设为第一个值,右边和左边被设为第二个值;如果有三个值,顶部被设为第一个值,左、右设置为第二个值,底部设置为第三个值;如果有四个值,它们分别适用于上、右、下、左

  body { margin: 2em }         /* all margins set to 2em */
  body { margin: 1em 2em }     /* top & bottom = 1em, right & left = 2em */
  body { margin: 1em 2em 3em } /* top=1em, right=2em, bottom=3em, left=2em */

上面最后一条规则的例子:

  body {
    margin-top: 1em;
    margin-right: 2em;
    margin-bottom: 3em;
    margin-left: 2em;    /* copied from opposite side (right) */
  }

8.3.1 折叠外边距(Collapsing margins)

在CSS中,两个或两个以上的盒子的外边距(可能是也可能不是相邻元素)可能结合成单个的外边距。这种现象称之为 折叠 ,结果就是合并的外边距称之为 折叠外边距(collapsed margin)

译者注:这里是重点

相邻盒子垂直方向上的折叠外边距,除了:

  • 根元素的盒子不折叠

  • 如果一个有空隙的元素的上下外边距相邻,其外边距将同其后同胞的相邻外边距折叠,但不同父块的下外边距折叠

水平外边距不折叠。

两个外边距相邻,当且仅当:

  • 属于同一个块格式上下文档流块级框中

  • 没有行盒、空隙、内边距和边框分隔它们

  • 盒边缘垂直相邻,也就是说,满足以下形式之一:

盒上外边距及其第一个文档流内子盒的上外边距

盒下外边距及下一个文档流内的同胞盒的上外边距

如果父盒的高度计算值为 auto ,其最后一个文档流内子盒的下外边距及父盒的下外边距

如果一个盒不建立新的块格式化上下文、 min-height 计算值为零、 height 计算值为零或 auto 、没有在文档流内的子盒,其上下外边距

如果一个折叠外边距与另一外边距的任何一边相邻,则视二者相邻

注意:不是同胞或祖先关系的元素也可以产生相邻外边距

注意:上述规则表明了:

  • 一个浮动的盒子与其他的盒子不会发生外边距坍塌,即使是浮动盒子和它内部的正常流中的孩子们

  • 自身建立了新的 BFC 的元素的外边距不会与它的处于正常流的孩子们的外边距重叠

  • inline-block 盒子的外边距不会坍塌,即使是它内部的正常流中的孩子们

* 一个正常流元素的 margin-bottom 与它下一个正常流的兄弟元素的 margin-top 会产生折叠,除非它们之间存在间隙(clearance

  • 一个正常流元素的 margin-top 与其第一个正常流的子元素的 margin-top 产生折叠,条件为父元素不包含 paddingborder ,子元素不包含 clearance

  • 一个 heightauto 并且 min-height0 的正常流元素的 margin-bottom 会与其最后一个正常流子元素的 margin-bottom 折叠,条件为父元素不包含 paddingborder ,子元素的 margin-bottom 不与包含 clearancemargin-top 折叠

  • 一个不包含 border-topborder-bottompadding-toppadding-bottom 的正常流元素,并且其 height0automin-height0,其里面也不包含行盒(line box),其自身的 margin-topmargin-bottom 会折叠

当两个及以上外边距折叠,合并后的外边距宽度是发生折叠的外边距中的最大宽度。如果发生折叠的外边距中有负数,则为最大正数相邻外边距减去最小负数相邻外边距的绝对值。如果不存在正数外边距,则为零减去最小负数相邻外边距的绝对值

如果一个盒的上下外边距相邻,则外边距可能穿过盒而折叠 Collapse Through It 。这种情况下,元素的定位取决于它同其他外边距折叠的元素的关系

  • 如果该元素的外边距同其父元素的上外边距折叠,则该盒的上边框边缘同其父元盒的上边框边缘相同

  • 否则,要么该元素的父元素的外边距不折叠,要么只有父元素的下外边距折叠。如果该元素下边框非零,则上边框边缘的位置不变

需要注意的是,被折叠穿过的元素的定位对其他外边距折叠的元素的定位无影响;其上边框边缘的定位仅用于布局其后代元素


8.4 内边距属性: padding-top, padding-right, padding-bottom, padding-left, 和 padding

内边距属性指定了一个盒子内部区域的宽度。padding属性可以指定为上右下左四个值。这个属性适用于所有元素,但垂直边缘不会对未替换的内联元素产生任何影响

本节定义的 <padding-width> 值类型,它可以是以下几个值:

  • 长度

指定的固定宽度

  • 百分比

按照百分比指定包含块的宽度

与外边距不同,内边距的边值属性不能为负值,与外边距一样,内边距的百分比值是指生成框的包含块的宽度

padding-top, padding-bottom, padding-bootom, padding-left :

值:<padding-width> | 继承

初始值: 0

适用于:所有元素,除表格标题、表格和内联表格外

继承:no

百分比: 取决于包含块的宽度

媒体查询: visual

计算值: 指定的值或百分比

这些属性设置了一个盒子的顶部,右边,底部和左填充

  blockquote { padding-top: 0.3em }

margin :

值:<padding-width> {1到4个值} | 继承

初始值: 参见上述属性的值

适用于:所有元素,除表格标题、表格和内联表格外

继承:no

百分比: 取决于包含块的宽度

媒体查询: visual

计算值: 参见上述属性的值

padding 属性比起来同时设置 padding-top, padding-right, padding-bottom, padding-left 更为简洁,但样式是一模一样的

如果 padding 只有一个值,它设置所有的四个属性;如果有两个值,则顶部和底部被设为第一个值,右边和左边被设为第二个值;如果有三个值,顶部被设为第一个值,左、右设置为第二个值,底部设置为第三个值;如果有四个值,它们分别适用于上、右、下、左

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

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

上面的例子中指定一个 1em 垂直填充(padding-toppadding-bottom)和 2em 的空白(padding-rightpddding-left 填充)。em 单位是相对于元素的字体大小:1em 等于在使用字体的大小


8.5 边框属性

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

值得注意的是,用户代理可能按照不同的方式渲染边框(例如,button ,menu 等)

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

边框宽度属性指定了边框边缘的宽度。这个属性通过 <boder-width> 指定值,可能是下面这些值:

thin : 较细的边框

medium : 中等粗的边框

thick : 较粗的边框

<length> : 指定一个确定的值。下面的关系一定是:

thin <= medium <= thick

此外,这些宽度必须是常数

boder-top-width , border-right , border-bottom-width , border-left-width :

值:<border-width> | 继承

初始值: medium

适用于:所有元素

继承:no

百分比: N/A

媒体查询: visual

计算值: 绝对长度;如果边框样式为 nonehidden 则为 0

这些属性设定了盒子顶部,右边,底部,左边边框

border-width :

值:<border-width> {1-4个属性} | 继承

初始值:参见上述属性

适用于:所有元素

继承:no

百分比: N/A

媒体查询:visual

计算值:参见上述属性

border 属性比起来同时设置 border-top, border-right, border-bottom, border-left 更为简洁,但样式是一模一样的

如果 border 只有一个值,它设置所有的四个属性;如果有两个值,则顶部和底部被设为第一个值,右边和左边被设为第二个值;如果有三个值,顶部被设为第一个值,左、右设置为第二个值,底部设置为第三个值;如果有四个值,它们分别适用于上、右、下、左

下面这个例子中,注释解释了上下左右各边的值:

  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 | 继承

初始值:color 的颜色值

适用于:所有元素

继承:no

百分比: N/A

媒体查询:visual

计算值:根据颜色值计算

border-color :

值:[ <color> | transparent ] {1-4个值} | 继承

初始值:color 的颜色值

适用于:所有元素

继承:no

百分比: N/A

媒体查询:visual

计算值:参见上述属性

border-color 属性设定了四个边框的颜色。它的值可能是以下:

<color> : 指定一个确定的值

transparent : 边框是透明的(即使它有宽度)

border-color 属性可能有1到4个值,但是不同于 border-width

如果一个元素的边框没有指定一个确定的值,用户代理强制 color 属性的值作为边框颜色的计算值

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

边框样式属性指定了盒子边框的样式(solid, double, dashed 等)。这个属性可以通过 border-style 指定值,值可能是以下:

none : 无边框,边框宽度的计算值为零

hidden : 和 none 一样,除了 border conflict resolution for table elements

dotted : 边框是一系列的点

dashed : 边框是一系列的短线段

solid : 边框是一条线段

double : 边框是双实心线。它们之间的间隙等于边框宽度

groove : 边框看起来像是嵌入的三角

ridge : 边框看起来好像是凸出的三角

inset : 边框看起来像内嵌

outset : 边框看起来像凸出

所有边框都是在盒子边框的背景上渲染的。grooverideginsetoutset 的颜色取决于元素的边框颜色属性,但用户代理可能会选择自己的算法来计算实际使用的颜色。例如,如果 border-color 的的值为 silver,然后用户代理可以使用从白色到深灰色的渐变颜色来表示一个倾斜的边框

border-top-style, border-right-style, border-bottom-style, border-left-style :

值:<border-style> | 继承

初始值:none

适用于:所有元素

继承:no

百分比: N/A

媒体查询:visual

计算值:视情况而定

border-style :

值:<border-style> {1-4个值} | 继承

初始值:参见上述属性

适用于:所有元素

继承:no

百分比: N/A

媒体查询:visual

计算值:参见上述属性

border-style 属性设定了四个边框的样式。它可以有1到4个值,但和 border-width 不同

  #xy34 {
    border-style: solid dotted
  }

上面的例子,水平边框将是 solid , 垂直边框将是 dotted

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> ] | 继承

初始值:参见上述属性

适用于:所有元素

继承:no

百分比: N/A

媒体查询:visual

计算值:参见上述属性

这个属性设定了盒子的顶部,底部和左右的属性

  h1 { border-bottom: thick solid red }

上面的规则将设置 h1 边框的宽度,样式和颜色。省略值被设置为其初始值。因为下面的规则没有指定边框颜色,边框将由 color属性指定颜色:

  h1 { border-bottom: thick solid }

border :

值:[ <border-width> || <border-style> || <border-top-color> ] | 继承

初始值:参见上述属性

适用于:所有元素

继承:no

百分比: N/A

媒体查询:visual

计算值:参见上述属性

border 属性可以同时设置盒子边框的宽度,颜色和样式。不同于 marginpadding 属性,border 属性不能同时设置四个边框为不同值。要这样做,必须明确指定一个或多个边框的属性

例如,下面第一条规则就等于四条规则的集合:

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

因为,在一定程度上,规则有优先级,其中的规则指定的顺序是重要的

看下面这个例子:

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

在上面的例子中,左边框的颜色是 black , 其它边框颜色是 red 。原因是 border-left 设置了宽度,样式和颜色。因为 border-left 没有明确指定颜色值,它将从 color 的值获取。实际上,color 属性和 border-left 属性并不相关


8.6 格式化上下文中内联元素的盒模型

对每个行盒而言,用户代理必须按视觉顺序(而非逻辑顺序)渲染其生成的行内盒的外边距、边框和内边距

当元素 direction 属性值为 ltr ,元素呈现的第一个行盒的最左生成盒拥有左外边距、左边框和左内边距,而元素呈现的最后一个行盒的最右生成盒拥有右内边距、右边框和右外边距

当元素 direction 属性值为 rtl ,元素呈现的第一个行盒的最右生成盒拥有右外边距、右边框和右内边距,而元素呈现的最后一个行盒的最左生成盒拥有左内边距、左边框和左外边距



上一篇 常用meta整理

Comments