CSS 之盒模型

盒模型是CSS中的一个重要概念,它是元素大小的呈现方式。Every Element In Web Design Is A Rectangular Box.

1. 一些基本概念

在学习盒模型之前,需要了解一些有关盒子的基本概念,有助于帮我们更好地理解盒模型的内容。
① 非替换元素:如果元素的内容包含在文档中,则称之为非替换元素。
② 替换元素:指用作为其他内容占位符的一个元素,最典型的例子就是 img 元素。
③ 块级元素:这类元素在正常流中时,会在其框之前和之后生成「换行」,所以处以正常流中的块级元素会垂直摆放。
④ 行内元素:这类元素不会之前和之后生成「行分隔符」,他们是块级元素的后代。行内元素可以继承块元素,反之则不允许。
⑤ em 框:即字符框,在 CSS 中,font-size 的值确定了各个 em 框的高度。
⑥ 内容区:在非替换元素中,是元素中各字符的 em 框串在一起构成的框;在替换元素中,内容区就是元素的固有高度再加上可能有的外边距、边框或内边距。
⑦ 行内框:对于非替换元素,元素行内框的高度刚好等于 line-height 的值;对于替换元素,元素行内框的高度则恰好等于内容区高度。
⑧ 行框:为该行中出现的行内框的最高点和最低点的最小框。

2. 盒类型

CSS 可以使用属性 display 来影响元素的显示方式。

下面主要介绍几种常用的元素显示方式:
① inline:元素作为行内元素显示。
② block:元素作为块状元素显示。
③ inline-block:元素为块状元素和行内元素的混合。他会作为替换元素放置于行中;在行内块元素内部,会像块级元素一样设置内容的格式。
④ run-in:使某些块级元素作为下一个元素的行内部分。只有当 run-in 框后面是一个块级框时 run-in 才会起作用。
⑤ list-item:将元素作为列表来显示,并可以为其添加列表样式。
⑥ none:即关闭一个元素的显示。当你使用 none 时,其所有后代元素的显示也会被关闭。

3. 盒模型

一个完整的盒模型由外而内包括:边距(margin)、边框(border)、填充(padding)、内容(content)。

3.1 元素的宽度和高度

3.1.1 width

width 定义了内容区的宽度。正常流中块级元素的水平部分总和就等于父元素的 width。

水平格式化的 7 大属性为:margin-leftborder-leftpadding-leftwidthmargin-rightborder-rightpadding-right。这 7 个属性中,只有 3 个属性可以设置为 auto:元素内容的 width,以及左、右外边距。
下面列举了水平属性使用 auto 的几种情况:
① 如果设置 widthmargin-leftmargin-right 中的某个值为 auto,而余下两个属性指定为特定的值,那么设置为 auto 的属性会确定所需的长度,从而使元素框的宽度等于父元素的 width。
② 如果这 3 个值都设置为非 auto 的某个值,CSS 称之为「过分受限」,此时总会将 margin-right 的值强制为 auto。
③ 如果两个外边距都显式地设置,而 width 设置为 auto,width 值将设置为所需的某个值,从而达到需要的总宽度(即父元素的内容宽度)。
④ 如果两个外边距都设置为 auto,他们会设置为相等的长度,从而使元素在其父元素中居中。
⑤ 若将某个外边距以及 width 值设置为 auto,设置为 auto 的外边距会减为 0。
⑥ 若 3 个元素都设置为 auto,两个外边距都会设置成 0,而 width 会尽可能地宽。
⑦ 若替换元素的 width 值为 auto,元素的宽度则是内容的固有宽度。

3.1.2 height

height 定义了内容区的高度。正常流中块级元素的垂直部分总和就等于父元素的 height。

垂直格式化也有 7 大属性,分别为:margin-topborder-toppadding-topheightmargin-bottomborder-bottompadding-bottom。这 7 个属性中,也只有 3 个属性可以设置为 auto:元素内容的 height,以及上、下外边距。
下面列举了垂直属性使用 auto 的几种情况:
① 如果正常流中一个元素的 margin-topmargin-bottom 设置为 auto,他会自动计算为 0。
② 如果块级正常流元素的 height 设置为 auto,显示时其高度将恰好足以包含其内联内容(包括文本)的行盒。

垂直格式化的另一个重要方面是垂直相邻外边距的合并。
① 一般地,两个外边距中较小的一个会被较大的一个合并。
② 当在包含快上设置边框或者内边距时,会使其子元素的外边距包含在包含快内。
③ 如果垂直外边距都设置为负值,浏览器会取两个外边距绝对值的最大值。
④ 如果一个正外边距和一个负外边距合并,会从正边距减去这个负边距的绝对值,即负值增加到正值中。

PS:元素的宽度、高度不能应用到行内非替换元素。

3.2 外边距

设置外边距会在元素外创建额外的「空白」,该「空白」通常指不能放其他元素的区域。

margin 的取值顺序很重要,应当遵循以下方式:

margin:  top   right   bottom   left

另外,margin 取值的时候可以混和使用各种类型的长度值,甚至可以混合使用百分数值和长度值。

CSS 针对值重复的情况允许为外边距指定少于 4 个值。
① 如果缺少左外边距的值,则使用右外边距的值。
② 如果缺少下外边距的值,则使用上外边距的值。
③ 如果缺少右外边距的值,则使用上外边距的值。

当你只想设置单边外边距的值,而不想影响其他外边距时,CSS 也提供了单边的外边距属性。

margin 值可以为负数,但是可能会导致元素超出其父元素,或者与其他元素重叠,所以需要合理使用负外边距的值。
PS:在向一个行内非替换元素应用外边距时,它对行高没有任何影响,但是左右外边距的设置是有效的。

3.3 边框

元素的边框就是围绕元素内容和内边距的一条或多条线。一般地,元素的背景会在外边框边界处停止。
每个边框都有 3 个方面:其宽度或粗细、其样式和外观、以及其颜色。

3.3.1 边框宽度

边框宽度控制着边框的粗细,其默认值为 medium。

我们也可以单独为某条边框设置边框宽度。

3.3.3 边框样式

边框样式控制着边框的显示方式,其默认值为 none,即没有样式,因此也不显示边框。
border-style 的值可以采用 top - right - bottom - left 的顺序,也可以使用值复制的方式表示。

同样地,如果你只想设置单边边框的样式的值,而不想影响其他边边框样式,可以为元素设置单边的边框样式属性。

3.3.3 边框颜色

默认的边框颜色是元素本身的前景色。

同样地,CSS 为单边的边框颜色提供了一些属性,从而不影响其他边上的颜色设置。

3.3.4 边框简写

CSS 为边框创造了简写的单边边框属性,为单边边框属性的设置提供了方便。需要注意的是,单边边框的属性设置只能应用到一条特定的边,故每种值只能有一种。

同样地,CSS 为全局的边框属性提供了简写。

3.4 内边距

元素框的内边距在边框和内容区之间。默认地,元素没有内边距。

同样地,CSS 为单边的边框内边距提供了一些属性,从而不影响其他边上的内边距。

4. 盒相关属性

4.1 盒子的隐藏

CSS 属性 visibility 允许从用户的视线中隐藏盒子。

当使用 hidden 的属性值时会隐藏元素,但是其他元素的布局不改变,相当于此元素变成透明。若不希望显示空白,可以使用 display 属性并设置成 none。

4.2 盒子的阴影

CSS 属性 box-shadow 可以为盒子周围添加阴影。

text-shadow 一样,box-shadow 在使用时有 4 个值,分别为阴影水平偏移距离、阴影竖直偏移距离、阴影的模糊半径以及阴影的颜色。当有多个阴影时用逗号进行分隔即可。

除此之外,还可以通过添加一个可选的关键字 inset 来在盒子内部添加阴影。该阴影只添加于盒子内部,超出盒子边框的部分将被裁剪。

4.3 盒子内容的溢出

CSS 属性 overflow 来指定如何显示盒子中容纳不下的内容。

① 使用 hidden 属性值时,内容将被剪裁以适合填充框。 不提供滚动条。
② 使用 scroll 属性值时,内容将被滚动显示,并提供滚动条。
③ 当使用两个属性值时,第一个关键字将应用于 overflow-y,第二个关键字应用于overflow-x

我们也可以单独指定水平或者垂直方向上如果内容超出盒容纳范围时的显示方法。

4.4 盒子的宽高计算方式

CSS 属性 box-sizing 用于更改用于计算元素宽度和高度的默认的 CSS 盒子模型。

① 当使用 content-box 属性值时,元素的宽度和高度不包括内部的补白区域以及边框的宽度,该值为默认值。
② 当使用 border-box 属性值时,元素的宽度和高度包括内部的补白区域以及边框的宽度。

5. 参考文档

[1] CSS 权威指南
[2] MDN 文档:盒子模型