CSS盒模型

参考

  1. MDN中对The box model的讲解(English)
  2. 杭州饥人谷前端课程

1. 通俗理解盒模型

通俗的或专业的说,盒(box)的实质是容器(container)。既然是容器,我们就可以将它拿碗来类比。下图是一张丑丑的宜家碗(图来自网络):

宜家碗

当我们计算一个桌子上能放几碗饭、多少饭时,我们通常会计算这样几个因素:

  • 碗的直径
  • 碗的厚度
  • 碗与碗之间的距离

虽然例子有点牵强,但这非常有助于我们理解盒模型。回到正题中。在学过HTML之后,我们发现html标签(tag)的实质是内容容器,也就可以类比为一个一个的碗。CSS盒模型正是基于这种假设展开的。

怎样类比呢?

  • 内容(content)放到碗中。
  • 剩下的事情就是看是装在薄薄的不锈钢碗还是装在厚瓷大碗中,当然,你愿意的话也可以放在厚重的重庆火锅里。(设置碗的厚度)
  • 最后就是摆桌子啦,摆成一桌满汉全席还是一桌地摊般凌乱,全看怎么摆(设置碗与碗的距离)

而在网页中,负责摆桌子的就是css

这样一来就很容易理解了。

2. 两种“碗”--块级盒子(Block box) 和 内联盒子(Inline box)

在CSS中我们通用两种碗--块级盒子内联盒子1。这两种盒子在页面流(page flow)中的表现是不同的,也就是两种盒子在页面中的显示方式不同。

块级盒子的特征如下1

  • 每个元素占一行。比如并排的10个
    元素就会占据10行。
  • 会在行内扩展,以填充所有可用空间。这就意味着,大多数情况下块级盒子会和元素一样宽。
  • 可以使用widthheight指定宽度与高度。
  • 指定paddingmarginborder属性会将其他盒子“推开”。

第二条也就是说,每个块级元素会尽可能地占据一整行,不论实际内容如何。

常见的块级盒子标签有:

  • ~

内联盒子的特征如下1

  • 从左到右,盒子不会换行。
  • widthheight无用。
  • 垂直方向的paddingmarginborder属性不会“推开”其他盒子。
  • 水平方向的paddingmarginborder属性才会“推开”其他盒子。

常见的内联盒子标签有:

除了上两者之外,还有一种结合类型:inline-block。特征如下:

  • inline相似,从左到右不换行
  • block相似,可以使用widthheight

3. 正式理解盒模型

那么什么是盒模型呢?回想第一部分所举的“碗”的例子。一个碗,我们可以计量它的直径(半径)、厚度、两碗间距离。同样的,一个盒(box),我们可以计量的部分如下:

  • content box:这个区域是用来显示内容的,大小可以通过设置widthheight。类比:用来装米饭的部分
  • padding box:包围在内容区域外部的空白区域; 大小通过padding相关属性设置。类比:在碗上还套了个袋
  • border box:边框盒包裹内容和内边距。。大小通过border相关属性设置。类比:碗的厚度
  • margin box:这是最外面的区域,是盒子和其他元素之间的空白区域。大小通过margin相关属性设置。类比:两碗距离。

可以在浏览器(Chrome、Edge、Firefox,前俩某种程度上是一回事)中按F12用开发者工具查看盒模型。如下图:

image.png

在使用时,我们可以使用两种盒模型:

  • content-box:内容是盒子的边界
  • border-boxborder是盒子的边界

一般情况下用后者,计量省事的多。有两个计算公式要记得:

  • content-boxwidth:content的宽度
  • border-boxwidth:content + padding + border

俩例子:

例1:content-box

content-box

可以看出,光内容就占了100px的宽度。

例2:border-box

border-box

内容+padding+border共计100px

示例代码

4. margin合并与阻止它

如果在父子元素与兄弟元素指定了margin元素的大小,则会发生margin合并现象。举个例子说明,我们在word排版时,会指定段与段之间的距离,指定段前0.5行,段后0.5行,这样一来两段便可以相距1行。但在CSS中,实际效果是如果这样指定的话,两段相距的是0.5行。原因是发生了margin合并

那么,如何阻止margin合并现象的发生呢?

在css中,发生margin合并有两种情况:

  • 父子合并(学过面向对象编程的都懂,也就是子元素继承父元素的margin)
  • 兄弟合并(如上面的设置段间距的例子)

取消也分为上两种情况。

父子合并的阻止合并的方法有如下:

  • 可以用paddingborder挡住
  • 也可以用overflow : hidden挡住
  • 还可以用display: flex

兄弟合并的方法如下:

  • inline-block

你可能感兴趣的:(CSS盒模型)