CSS 盒模型、标准模式与怪异模式
本文对原文进行了重新整理和勘误。需要特别区分两个容易混淆的概念:标准模式/怪异模式是文档解析模式,而
content-box/border-box是 CSS 的尺寸计算方式。二者相关但不是同一回事。
目录
- 一、什么是 CSS 盒模型
- 二、盒模型的四个部分
- 三、content-box 与 border-box
- 四、标准模式与怪异模式
- 五、DOCTYPE 的作用
- 六、实际尺寸计算
- 七、全局使用 border-box
- 八、盒模型中的 margin、padding 和 border
- 九、不同布局中的盒模型
- 十、常见问题和调试方法
- 十一、总结
一、什么是 CSS 盒模型
浏览器会把元素渲染成一个矩形盒子。这个盒子由内容、内边距、边框和外边距组成,这种计算元素尺寸的规则就是 CSS 盒模型(Box Model)。
┌──────────────────────────────────────────────┐
│ margin │
│ ┌────────────────────────────────────────┐ │
│ │ border │ │
│ │ ┌──────────────────────────────────┐ │ │
│ │ │ padding │ │ │
│ │ │ ┌────────────────────────────┐ │ │ │
│ │ │ │ content │ │ │ │
│ │ │ └────────────────────────────┘ │ │ │
│ │ └──────────────────────────────────┘ │ │
│ └────────────────────────────────────────┘ │
└──────────────────────────────────────────────┘
从内到外依次是:
content → padding → border → margin

二、盒模型的四个部分
2.1 content:内容区域
内容区域用于显示文本、图片、子元素等内容。默认情况下,CSS 的 width 和 height 指的是内容区域的尺寸。
.box {
width: 200px;
height: 100px;
}
在默认的 content-box 模式下,width: 200px 表示内容宽度为 200px,不包含 padding 和 border。
2.2 padding:内边距
Padding 是内容与边框之间的空间,可以分别设置四个方向:
.box {
padding-top: 10px;
padding-right: 16px;
padding-bottom: 10px;
padding-left: 16px;
}
简写方式:
.box {
padding: 10px 16px;
}
顺序是:
上 右 下 左
Padding 属于元素盒子的一部分,可以显示背景色和背景图片;它不会像 margin 一样产生外部间距。
2.3 border:边框
Border 位于 padding 外侧:
.box {
border: 1px solid #ddd;
}
边框也会影响元素的实际尺寸。边框宽度、样式和颜色都可以分别设置:
.box {
border-width: 1px;
border-style: solid;
border-color: #ddd;
}
2.4 margin:外边距
Margin 用于控制元素与其他元素之间的距离:
.box {
margin: 24px auto;
}
Margin 不属于元素自身的 border box,也不会显示元素背景。它会影响元素在普通文档流中的外部占用空间。
需要注意:垂直方向相邻的普通块级元素可能发生外边距折叠,最终间距不一定等于两个 margin 的相加结果。Flex、Grid 容器中的子项通常不会发生传统的外边距折叠。
三、content-box 与 border-box
box-sizing 用于指定 width 和 height 的计算方式:
box-sizing: content-box;
box-sizing: border-box;
3.1 content-box
content-box 是默认值,声明的 width 和 height 只包含内容区域:
.box {
box-sizing: content-box;
width: 200px;
padding: 20px;
border: 10px solid #333;
}
实际 border box 宽度为:
200 + 20 + 20 + 10 + 10 = 260px
公式:
border-box 宽度 = width
+ padding-left + padding-right
+ border-left-width + border-right-width
3.2 border-box
border-box 会让声明的 width 和 height 包含内容、padding 和 border:
.box {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 10px solid #333;
}
此时:
border-box 总宽度 = 200px
content 宽度 = 200 - 20 - 20 - 10 - 10 = 140px

border-box 不包含 margin:
元素自身的 border-box 宽度 = width
包含左右 margin 的外部占用宽度 = width + margin-left + margin-right
3.3 box-sizing 不是怪异模式
下面两种配置完全是不同层面的概念:
/* CSS 尺寸计算方式 */
.box {
box-sizing: border-box;
}
<!-- HTML 文档解析模式提示 -->
<!doctype html>
box-sizing: border-box 可以在标准模式下正常使用,不会让浏览器进入怪异模式。
四、标准模式与怪异模式
4.1 标准模式
标准模式(no-quirks mode,也常被称为 standards mode)是浏览器按照现代 HTML 和 CSS 规范解析页面的模式。
在标准模式下:
box-sizing默认值是content-box;width默认只表示 content 宽度;- padding 和 border 会增加 border box 的尺寸;
- 可以通过 CSS 明确设置
border-box。
4.2 怪异模式
怪异模式(quirks mode)是浏览器为了兼容早期网页而保留的历史解析模式。它不是某个浏览器独有的“IE 盒子模型”,现代浏览器也会支持这种兼容模式。
缺少 DOCTYPE、DOCTYPE 格式错误或使用某些旧式 DOCTYPE,都可能触发怪异模式或有限怪异模式。怪异模式会影响一些历史布局行为,例如部分元素的宽高计算、表格和字体等。
不要依赖怪异模式实现布局。需要使用 border-box 时,应直接写 CSS:
*,
*::before,
*::after {
box-sizing: border-box;
}
4.3 两者的关系
| 概念 | 所属层面 | 作用 |
|---|---|---|
| 标准模式 / 怪异模式 | HTML 文档解析模式 | 决定浏览器如何兼容和解析旧式页面 |
content-box / border-box | CSS 尺寸计算规则 | 决定 width、height 是否包含 padding 和 border |
正确的理解是:
DOCTYPE 决定文档解析模式
box-sizing 决定元素尺寸计算方式
五、DOCTYPE 的作用
HTML5 推荐在文档第一行使用:
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>盒模型示例</title>
</head>
<body>
</body>
</html>
DOCTYPE 的主要作用是让浏览器进入标准解析模式,不是指定 content-box 或 border-box。
下面的写法是不完整或不推荐的:
<!-- 缺少 DOCTYPE,可能触发怪异模式 -->
<html>
可以在开发者工具控制台检查当前文档模式:
console.log(document.compatMode)
常见结果:
CSS1Compat:标准模式或有限标准模式;BackCompat:怪异模式。
六、实际尺寸计算
6.1 默认 content-box 示例
.box {
width: 200px;
height: 100px;
padding: 20px;
border: 10px solid #333;
margin: 16px;
}
水平方向计算:
content 宽度 = 200px
padding 宽度 = 20 + 20 = 40px
border 宽度 = 10 + 10 = 20px
border-box 宽度 = 200 + 40 + 20 = 260px
外部占用宽度 = 260 + 16 + 16 = 292px
垂直方向计算:
content 高度 = 100px
padding 高度 = 20 + 20 = 40px
border 高度 = 10 + 10 = 20px
border-box 高度 = 100 + 40 + 20 = 160px
如果只讨论元素自身的尺寸,应使用 content box 或 border box,不要把 margin 误认为元素宽度的一部分。
6.2 border-box 示例
.box {
box-sizing: border-box;
width: 200px;
height: 100px;
padding: 20px;
border: 10px solid #333;
margin: 16px;
}
此时:
border-box 宽度 = 200px
content 宽度 = 200 - 40 - 20 = 140px
包含左右 margin 的外部占用宽度 = 200 + 32 = 232px
6.3 width: auto
width 默认值是 auto。在普通块级格式化上下文中,块级元素通常会尽可能占满包含块可用宽度,但实际尺寸还会受到 margin、padding、border、最小宽度和最大宽度影响。
不要把所有元素都简单套用固定宽度公式。Flex、Grid、绝对定位和替换元素都有自己的尺寸计算规则。
七、全局使用 border-box
现代项目中常见的写法是让所有元素继承 border-box:
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
这样写比直接给所有元素设置值更容易让后续组件单独覆盖:
.special-box {
box-sizing: content-box;
}
对于表单控件,浏览器默认值可能存在差异,统一设置 box-sizing 有助于让 input、textarea 和按钮的尺寸更加可预测:
button,
input,
textarea,
select {
box-sizing: border-box;
}
八、盒模型中的 margin、padding 和 border
8.1 Margin 不会显示背景
.box {
background: #e8f3ff;
margin: 20px;
padding: 20px;
}
背景色会覆盖 content 和 padding,默认还会绘制到 border 下方,但不会绘制到 margin 区域。
8.2 Padding 可能增加可点击区域
对于按钮和链接,适当使用 padding 可以增加触摸区域:
.button {
display: inline-flex;
min-height: 44px;
align-items: center;
padding-inline: 16px;
}
8.3 外边距折叠
普通块级元素的垂直 margin 可能折叠:
.first {
margin-bottom: 20px;
}
.second {
margin-top: 30px;
}
两者之间的实际垂直间距通常是 30px,而不是 50px。如果希望明确控制间距,可以使用:
- 父元素设置
display: flow-root; - 使用
padding; - 使用
border; - 使用 Flex 或 Grid 的
gap; - 使用
gap代替子元素之间的 margin。
.list {
display: flex;
flex-direction: column;
gap: 16px;
}
8.4 Inline 元素的盒模型
对普通 inline 元素设置 width 和 height 通常不会像块级元素一样生效:
.text {
display: inline;
width: 200px; /* 通常不会按预期生效 */
}
如果需要设置明确的宽高,可以使用:
.text {
display: inline-block;
width: 200px;
height: 40px;
}
九、不同布局中的盒模型
9.1 Flex 布局
box-sizing 仍然会影响元素的 width 和 height,但 Flex 还会根据 flex-basis、flex-grow、flex-shrink、最小尺寸等规则重新分配空间。
常见的横向溢出问题:
.layout {
display: flex;
}
.content {
min-width: 0;
flex: 1;
}
Flex 子项默认的 min-width: auto 可能导致长文本或宽表格撑破容器,必要时应设置 min-width: 0。
9.2 Grid 布局
Grid 轨道的尺寸还会受到 min-content 和 max-content 的影响。常见的防溢出写法是:
.layout {
display: grid;
grid-template-columns: minmax(0, 1fr) 240px;
gap: 16px;
}
9.3 绝对定位元素
绝对定位元素的 width、height、left、right 等属性会共同参与尺寸计算。其包含块通常由最近的定位祖先决定,不一定是视口。
十、常见问题和调试方法
10.1 元素明明设置了 200px,为什么实际宽度是 260px
通常是因为默认使用了 content-box:
box-sizing: content-box;
检查 padding 和 border,或者改为:
box-sizing: border-box;
10.2 width: 100% 加 padding 后溢出
.panel {
width: 100%;
padding: 20px;
}
在 content-box 下,实际宽度会变成 100% + 40px。解决方式:
.panel {
box-sizing: border-box;
}
或者使用全局规则。
10.3 为什么设置了 margin 却没有看到间距
可能是发生了垂直 margin 折叠,也可能是父元素、子元素或相邻元素的 margin 发生了合并。可以使用浏览器开发者工具查看盒模型和计算后的样式。
10.4 为什么设置了 height: 100% 没有效果
百分比高度依赖明确的父级高度。如果父元素高度是 auto,子元素的 height: 100% 通常没有可计算的参考值。
html,
body,
.page {
min-height: 100%;
}
实际项目中也可以考虑:
.page {
min-height: 100dvh;
}
10.5 如何检查当前是否为怪异模式
if (document.compatMode === 'BackCompat') {
console.warn('当前文档处于怪异模式')
}
开发者工具的 Elements 或 Computed 面板可以查看:
- content 尺寸;
- padding;
- border;
- margin;
box-sizing的最终值;- 元素的实际
getBoundingClientRect()尺寸。
const element = document.querySelector('.box')
console.log(element?.getBoundingClientRect())
10.6 盒模型不是唯一的尺寸来源
元素的最终尺寸还可能受到以下因素影响:
min-width、max-width、min-height、max-height;- Flex 或 Grid 的空间分配;
aspect-ratio;- 字体和文本换行;
- 滚动条;
transform;- 绝对定位;
- 浏览器默认样式。
因此不能只看 CSS 文件中的 width 就判断最终渲染尺寸。
十一、总结
- CSS 盒模型从内到外是
content → padding → border → margin; - 默认
box-sizing是content-box,width和height只表示内容区域; border-box会让声明的宽高包含 padding 和 border,但不包含 margin;box-sizing是 CSS 尺寸计算规则,不等于怪异模式;- 标准模式和怪异模式是 HTML 文档解析模式;
<!doctype html>用于触发标准模式,不负责指定content-box或border-box;- 怪异模式是历史兼容行为,不应作为现代布局方案;
- 现代项目通常使用全局
border-box,让尺寸计算更加直观; - Flex、Grid、百分比、最小最大尺寸等布局规则也会影响最终尺寸;
- 遇到宽度溢出或尺寸不符合预期时,应使用开发者工具检查完整盒模型。