前端基础

从盒子模型理解前端布局尺寸计算

这篇笔记记录一下我对 CSS 盒子模型的理解。 盒子模型是前端面试里非常常见的问题,但它不只是面试题。 写页面时很多奇怪的问题,最后都会回到盒子模型: 为什么设置了 width: 100px,实际占用不止 100px? 为什么两个元素之间距离比想象中大? 为什么加了 padding 后布局被撑破? 为什么 boxsiz

2026年6月13日7 分钟阅读
从盒子模型理解前端布局尺寸计算

这篇笔记记录一下我对 CSS 盒子模型的理解。

盒子模型是前端面试里非常常见的问题,但它不只是面试题。

写页面时很多奇怪的问题,最后都会回到盒子模型:

  • 为什么设置了 width: 100px,实际占用不止 100px?
  • 为什么两个元素之间距离比想象中大?
  • 为什么加了 padding 后布局被撑破?
  • 为什么 box-sizing: border-box 经常被全局设置?

后来我发现,盒子模型本质上是在回答一个问题:

text
一个元素在页面上到底占多大?

一个盒子由哪些部分组成

每个元素都可以粗略理解成一个盒子。

这个盒子从内到外有四层:

text
content
padding
border
margin

分别是:

部分含义
content内容区域,比如文字、图片、子元素
padding内容和边框之间的内边距
border边框
margin元素和其他元素之间的外边距

可以想象成:

text
margin
  border
    padding
      content

标准盒模型

默认情况下,CSS 使用标准盒模型。

例如:

css
.box {
  width: 100px;
  padding: 20px;
  border: 5px solid black;
  margin: 10px;
}

这里的 width: 100px 指的是 content 的宽度。

所以元素边框以内的实际宽度是:

text
content 100
+ padding-left 20
+ padding-right 20
+ border-left 5
+ border-right 5
= 150px

如果再算上左右 margin,它在布局中占据的总空间大概是:

text
150 + 10 + 10 = 170px

这就是很多人刚写 CSS 时容易困惑的地方。

设置了 width: 100px,视觉上却不止 100px。

IE 盒模型和 border-box

另一种常见计算方式是:

css
box-sizing: border-box;

这时:

css
.box {
  box-sizing: border-box;
  width: 100px;
  padding: 20px;
  border: 5px solid black;
}

width: 100px 表示 content + padding + border 加起来总共 100px。

也就是说:

text
总宽度 100
- 左右 padding 40
- 左右 border 10
= content 50

元素的边框外宽度就是 100px,不会因为 padding 和 border 额外撑大。

为什么常见全局设置 border-box

很多项目会在全局 CSS 里写:

css
*,
*::before,
*::after {
  box-sizing: border-box;
}

原因很简单:布局更容易算。

比如一个两列布局:

css
.left {
  width: 50%;
  padding: 20px;
}

.right {
  width: 50%;
  padding: 20px;
}

如果是标准盒模型,两列的 content 各占 50%,再加 padding,整体就可能超过 100%。

如果是 border-box,padding 包含在 50% 里面,就更符合直觉。

所以 border-box 不是改变了盒子结构,而是改变了 widthheight 的计算口径。

margin 不算在 width 里

无论是标准盒模型还是 border-box,margin 都不算进 width

比如:

css
.box {
  box-sizing: border-box;
  width: 100px;
  margin: 20px;
}

这个元素边框以内是 100px。

但它和其他元素排版时,左右还会各留 20px。

所以布局占用空间大概是:

text
20 + 100 + 20 = 140px

这也是为什么 width: 100% 再加左右 margin 时,容器可能会溢出。

padding 和 margin 的区别

padding 是盒子内部空间。

margin 是盒子外部空间。

例如一个按钮:

css
.button {
  padding: 8px 12px;
  margin-right: 16px;
}

padding 会让按钮内部文字和边框之间更舒展。

margin-right 会让这个按钮和右边的元素拉开距离。

可以这样记:

text
想让自己里面宽一点,用 padding。
想和别人离远一点,用 margin。

margin 合并

面试里也经常问 margin 合并。

最常见的是垂直方向相邻块级元素的 margin 会合并。

例如:

css
.a {
  margin-bottom: 20px;
}

.b {
  margin-top: 30px;
}

这两个元素之间的距离通常不是:

text
20 + 30 = 50px

而是取较大的那个:

text
30px

这叫 margin collapse。

水平 margin 不会这样合并。

Flex 和 Grid 布局里的子项也不会按普通块级流那样发生典型的 margin 合并。

所以现代布局里,很多团队更喜欢用 gap 来控制元素间距。

width、clientWidth、offsetWidth 的区别

写 JavaScript 读取元素尺寸时,也会碰到盒子模型。

常见属性有:

属性大概包含
clientWidthcontent + padding
offsetWidthcontent + padding + border
scrollWidth实际可滚动内容宽度

例如:

css
.box {
  width: 100px;
  padding: 20px;
  border: 5px solid black;
}

标准盒模型下:

text
clientWidth = 140
offsetWidth = 150

如果内容溢出,scrollWidth 可能更大。

调试滚动容器、虚拟列表、拖拽布局时,这些概念会非常有用。

display 会影响盒子的排列方式

盒子模型描述的是元素自身尺寸结构。

但元素怎么和其他盒子排列,还要看 display

常见情况:

display特点
block独占一行,可以设置宽高
inline跟随文字流,不容易直接设置宽高
inline-block行内排列,同时可以设置宽高
flex子元素进入弹性布局
grid子元素进入网格布局

所以盒子模型和布局模型不是一回事。

盒子模型回答:

text
这个元素自己的尺寸怎么算?

布局模型回答:

text
这个元素和兄弟元素怎么排列?

面试常问怎么回答

如果面试问“什么是盒子模型”,可以这样答:

text
CSS 盒子模型描述一个元素由 content、padding、border、margin 组成。
默认标准盒模型里,width 和 height 只表示 content 区域。
如果设置 box-sizing: border-box,width 和 height 会包含 padding 和 border。
margin 在两种模型里都不算进 width 和 height。

如果继续问“为什么常用 border-box”,可以说:

text
因为它让元素的视觉尺寸更符合我们设置的 width 和 height,
padding 和 border 不会额外把元素撑大,响应式布局更容易计算。

如果问“margin 合并是什么”,可以说:

text
普通文档流中,相邻块级元素的垂直 margin 可能会合并,
最终距离通常取较大的那个,而不是简单相加。

我最后想通的地方

盒子模型不是一个孤立概念。

它贯穿了页面布局里的很多细节:

text
元素宽高怎么算
padding 会不会撑开盒子
border 算不算在尺寸里
margin 为什么有时没有相加
JS 读取到的尺寸为什么和 CSS 不一样

我现在更愿意把它理解成前端布局的基础坐标系。

只要能清楚地区分:

text
content
padding
border
margin
box-sizing

很多看起来玄学的 CSS 尺寸问题,就能一步一步算出来。