1. 基础框盒模型介绍

# 1. 基础框盒模型介绍

# 简明概要

当对一个文档进行布局(lay out)的时候,浏览器的渲染引擎会根据标准之一的 CSS 基础框盒模型CSS basic box model),将所有元素表示为一个个矩形的盒子(box)。CSS 决定这些盒子的大小、位置以及属性(例如颜色、背景、边框尺寸…)。

每个盒子由四个部分(或称区域)组成,其效用由它们各自的边界(Edge)所定义(原文:defined by their respective edges,可能意指容纳、包含、限制等)。如图,与盒子的四个组成区域相对应,每个盒子有四个边界:内容边界 Content edge内边距边界 Padding Edge边框边界 Border Edge外边框边界 Margin Edge

box-model

盒模型由以下属性组成,由外到内用公式表示就是:box = margin + border + padding + content。除了content(不是属性,作为盒模型扩展理解使用),其余属性都包含left、right、top和bottom等扩展属性。

  • margin:边距,外部透明区域,负责隔离相邻盒子
  • border:边框,内部着色区域,负责隔离边距和填充,包含widthstylecolor三个扩展属性
  • padding:填充,内部着色区域,负责扩展盒子内部尺寸
  • content:内容,以文本节点存在的占用位置

TIP

padding着色随background-color而变,可用background-clip隔离.

# CSS盒子类型

由于历史原因,盒模型分化成两种类型,分别是标准盒模型怪异盒模型

CSS3里提供一个属性用于声明盒模型的类型,它就是box-sizing

  • content-box:标准盒模型(默认)
  • border-box:怪异盒模型

但是它不具备继承性,若全局统一盒模型,那只能使用*声明box-sizing了。

# 标准盒模型

标准盒模型是W3C规范的标准,由margin + border + padding + content组成。与上述提到的公式一模一样,节点的width/height只包含content,不包含paddingborder

节点的尺寸计算公式如下。

  • 横向margin-[left/right] + border-[left/right]+ padding-[left/right] + width
  • 纵向margin-[top/bottom] + border-[top/bottom]+ padding-[top/bottom] + height

节点的宽高计算公式如下。

  • 横向width = width
  • 纵向height = height

# 怪异盒模型

怪异盒模型又名IE盒子模型,是IExplore制定的标准,由margin + content组成。与上述提到的公式一不同,节点的width/height包含borderpaddingcontent

节点的尺寸计算公式如下。

  • 横向margin-[left/right] + width(包含border-[left/right]padding-[left/right])
  • 纵向margin-[top/bottom] + height(包含border-[top/bottom]padding-[top/bottom])

节点的宽高计算公式如下。

  • 横向width = border + padding + width
  • 纵向height = border + padding + height

下面用代码来展示两者的区别:

.content-box{
  width: 200px;
  height: 200px;
  background-color: aqua;
  box-sizing: content-box;
  padding: 30px;
  border: 10px dotted green;
  margin: 20px;
}
.border-box{
  width: 200px;
  height: 200px;
  background-color: rgb(255, 187, 0);
  box-sizing: border-box;
  padding: 30px;
  border: 10px dotted rgb(0, 2, 128);
  margin: 20px;
}

# 两种盒子的区别

标准盒模型和怪异盒模型的区别

外边距区域的大小由 margin-top (opens new window)margin-right (opens new window)margin-bottom (opens new window)margin-left (opens new window),和简写属性 margin (opens new window) 控制。在发生[外边距合并]的情况下,由于盒之间共享外边距,外边距不容易弄清楚。

最后,请注意,除[可替换元素]外,对于行内元素来说,尽管内容周围存在内边距与边框,但其占用空间(每一行文字的高度)则由 line-height (opens new window) 属性决定,即使边框和内边距仍会显示在内容周围。

新增加

在 [CSS 盒子模型]的默认定义里,你对一个元素所设置的 width (opens new window)height (opens new window) 只会应用到这个元素的内容区。如果这个元素有任何的 border (opens new window)padding (opens new window) ,绘制到屏幕上时的盒子宽度和高度会加上设置的边框和内边距值。这意味着当你调整一个元素的宽度和高度时需要时刻注意到这个元素的边框和内边距。当我们实现响应式布局时,这个特点尤其烦人。

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

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

注: border-box不包含margin

box-sizing 属性被指定为下面列表中的关键字。

box-sizing = content-box

默认值,标准盒子模型。 width (opens new window)height (opens new window) 只包括内容的宽和高, 不包括边框(border),内边距(padding),外边距(margin)。注意: 内边距、边框和外边距都在这个盒子的外部。 比如说,.box {width: 350px; border: 10px solid black;} 在浏览器中的渲染的实际宽度将是 370px。

尺寸计算公式: width = 内容的宽度 height = 内容的高度

宽度和高度的计算值都不包含内容的边框(border)和内边距(padding)。

box-sizing = border-box

width (opens new window)height (opens new window) 属性包括内容,内边距和边框,但不包括外边距。这是当文档处于 Quirks模式 时Internet Explorer使用的[盒模型]。注意,填充和边框将在盒子内 , 例如, .box {width: 350px; border: 10px solid black;} 导致在浏览器中呈现的宽度为350px的盒子。内容框不能为负,并且被分配到0,使得不可能使用border-box使元素消失。

尺寸计算公式:

`width` = border + padding + 内容的宽度
`height` = border + padding + 内容的高度

# 正确使用"width:100%"

"width:100%"是一个很常用的属性,当对子元素这样设置的时候,子元素的宽度就等于父元素的宽度。 但是,这句话还不够准确。子元素的宽度指什么?子元素内容区域的宽度还是包括padding/border的总宽度?父元素的宽度指什么?父元素内容区域的宽度还是包括padding/border的总宽度?

<style>
	// css
.parent{
  margin:100px auto;
  width:600px;
  border:100px solid #ddd;
  padding:100px;
}
.child{
  width:100%;
  border:50px solid pink;
  padding:50px;
}
</style>
// html
<body>
  <div class='parent'>
    parent
     <div class='child'>
        child
     </div>
  </div>
</body>

父元素内容区域宽度:600px,padding:100px,border:100px,总宽度:1000px; 子元素内容区域宽度:600px,padding:50px,border:50px,总宽度:800px。 由此可知,子元素设置宽度的百分比是指子元素内容区域相对于父元素内容区域;同时,正是由于子元素设置宽度的百分比是指子元素内容区域相对于父元素内容区域,所以造成了子元素溢出了父元素

在以上示例中,我们没有设置box-sizing属性,因此box-sizing默认为content-box。现在,我们为元素设置box-sizing:content-box,再看看结果:

// css
*{
  box-sizing:border-box;
}

由图可知: 父元素内容区域宽度:200px,padding:100px,border:100px,总宽度:600px; 子元素内容区域宽度:0px,padding:50px,border:50px,总宽度:200px。

由此可知,当设置box-sizing:border-box时,子元素设置宽度的百分比是指子元素整个盒子区域相对于父元素内容区域

总结: 1、当设置"box-sizing:content-box"时,子元素设置宽度的百分比是指子元素内容区域相对于父元素内容区域; 2、当设置"box-sizing:border-box"时,子元素设置宽度的百分比是指子元素整个盒子区域相对于父元素内容区域; 3、如果想要正确使用"width:100%"这一属性,一定要设置"box-sizing:border-box",否则会造成子元素溢出。