# 盒模型

CSS的基础框盒模型, 浏览器根据元素所设置的盒模型来计算元素的高宽,边框,位置等信息,然后再进行渲染到页面上.

CSS盒模型由四个模块构成

  1. 内容边界
  2. 内边距边界
  3. 边框边界
  4. 外边框边界

# 内容区域 content area

由内容边界限制,容纳元素的真实内容,也即是元素内容所具备的真实宽度。

它的尺寸为内容宽度(content-width)和内容高度(content-height),它通常含有一个背景颜色(默认颜色为透明)或背景图像。

当元素的 box-sizing: content-box;(默认), 则此处的内容区域大小可以明确的由width,height,min-width,min-height,max-width,max-height设定。

# 内边距区域 padding area

由内边距边界限制,扩展自内容区域,负责延伸内容区域的背景,填充元素中内容与边框的间距。它的尺寸是 padding-box 宽度 和 padding-box 高度。

# 边框边界 border area

由边框边界限制,扩展自内边距区域,是容纳边框的区域。其尺寸为 border-box 宽度 和 border-box 高度。

# 外边框边界 margin area

由外边距边界限制,用空白区域扩展边框区域,以分开相邻的元素。它的尺寸为 margin-box 宽度 和 margin-box 高度。

# 包含块

一个元素的尺寸和位置经常受其包含块(containing block)的影响。大多数情况下,包含块就是这个元素最近的祖先块元素内容区,但也不是总是这样。

# 确定包含块

确定一个元素的包含块的过程完全依赖于这个元素的 position 属性:

  1. 如果 position 属性为 staticrelativesticky,包含块可能由它的最近的祖先块元素(比如说inline-block, blocklist-item元素)的内容区的边缘组成,也可能会建立格式化上下文(比如说 a table container, flex container, grid container, 或者是 the block container 自身)。
  2. 如果 position 属性为 absolute ,包含块就是由它的最近的 position 的值不是 static (也就是值为fixed, absolute, relativesticky)的祖先元素的内边距区的边缘组成。
  3. 如果 position 属性是 fixed,在连续媒体的情况下(continuous media)包含块是 viewport ,在分页媒体(paged media)下的情况下包含块是分页区域(page area)。
  4. 如果 position 属性是 absolutefixed,包含块也可能是由满足以下条件的最近父级元素的内边距区的边缘组成的:
    1. transformperspective 的值不是 none
    2. will-change 的值是 transformperspective
    3. filter 的值不是 nonewill-change 的值是 filter(只在 Firefox 下生效).
    4. contain 的值是 paint (例如: contain: paint;)

注意: 根元素(<html>)所在的包含块是一个被称为初始包含块的矩形。他的尺寸是视口 viewport 或分页媒体 page media .

# 根据包含块计算百分值

如上所述,如果某些属性被赋予一个百分值的话,它的计算值是由这个元素的包含块计算而来的。这些属性包括盒模型属性和偏移属性:

  1. 要计算 height topbottom 中的百分值,是通过包含块的 height 的值。如果包含块的 height 值会根据它的内容变化,而且包含块的 position 属性的值被赋予 relativestatic ,那么,这些值的计算值为 auto
  2. 要计算 width, left, right, padding, margin 这些属性由包含块的 width 属性的值来计算它的百分值。

# box-sizing

在盒子模型的默认定义里,你对一个元素设置的 widthheight 只会应用到这个元素的内容区。 如果这个元素有任何的 borderpadding ,绘制到屏幕上时的盒子宽度和高度会加上设置的边框和内边距值。

这意味着当你调整一个元素的宽度和高度时需要时刻注意到这个元素的边框和内边距。

box-sizing 属性可以被用来调整这些表现:

  • content-box默认值。如果你设置一个元素的宽为100px,那么这个元素的内容区会有100px 宽,并且任何边框和内边距的宽度都会被增加到最后绘制出来的元素宽度中。
  • border-box 告诉浏览器:你想要设置的边框和内边距的值是包含在width内的。也就是说,如果你将一个元素的width设为100px,那么这100px会包含它的border和padding,内容区的实际宽度是width减去(border + padding)的值。 但并不包含margin

# 参考资料

  1. 盒子模型 (opens new window)
  2. box-sizing (opens new window)
  3. 布局和包含块 (opens new window)