第 05 节 · 盒模型与布局流
第 05 节 · 盒模型与布局流
📌 版本信息:基于 CSS 现行规范(
box-sizing为稳定特性;2026-08-29 核对) 📚 来源:MDN 盒模型 | MDN 常规流
一、这一节的目标
- 精通盒模型四层结构:content / padding / border / margin
- 会用 DevTools 的盒模型图调试间距问题
- 分清块级元素与行内元素的排版规则
- 理解文档流(normal flow)与 margin 合并现象
- 会用
box-sizing: border-box解决"宽度失控"
二、盒模型:页面上一切都是盒子
一句话:浏览器把每个元素都画成一个矩形盒子,从内到外四层。
┌─────────────────────────────────────┐
│ margin(外边距:盒子与邻居的距离) │
│ ┌───────────────────────────────┐ │
│ │ border(边框) │ │
│ │ ┌─────────────────────────┐ │ │
│ │ │ padding(内边距: │ │ │
│ │ │ 内容与边框之间的呼吸空间) │ │ │
│ │ │ ┌───────────────────┐ │ │ │
│ │ │ │ content(内容) │ │ │ │
│ │ │ └───────────────────┘ │ │ │
│ │ └─────────────────────────┘ │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
类比快递:content 是商品,padding 是泡沫填充物,border 是纸箱壁,margin 是你和隔壁快递箱的间距。
.card {
width: 300px; /* 内容宽度(在默认盒模型下) */
padding: 16px; /* 四边内边距;也可分写 padding-top/right/bottom/left */
padding: 8px 16px; /* 简写:上下 8 左右 16 */
padding: 8px 16px 24px; /* 上 左右 下 */
padding: 8px 16px 24px 32px; /* 上 右 下 左(顺时针) */
border: 1px solid #ddd; /* 粗细 样式 颜色 */
margin: 0 auto 24px; /* 上 左右(auto=居中) 下 —— 水平居中的经典写法 */
}
三、box-sizing:宽度到底算哪一层?
默认盒模型(content-box)有个反直觉的坑:
/* 默认 content-box:width 只算内容! */
.box {
width: 300px;
padding: 20px;
border: 5px solid;
/* 实际占宽 = 300 + 20*2 + 5*2 = 350px!布局经常因此爆掉 */
}
行业解法:全站换成 border-box——width 直接算到边框为止,说 300 就是 300:
/* 现代项目标配:所有元素统一 border-box(直接抄进每个项目) */
*,
*::before,
*::after {
box-sizing: border-box;
}
⚠️ 这也是为什么 DevTools 里看到别人项目总带这一条。从今天起新项目第一行 CSS 就写它。
四、块级、行内、行内块
| 类型 | 典型标签 | 排版行为 |
|---|---|---|
| 块级 block | div p h1 section ul |
独占一行,默认宽度撑满父容器,可设宽高 |
| 行内 inline | span a strong img |
排成一行,宽高由内容决定,设宽高无效(水平方向 margin/padding 有效,垂直方向不推开别人) |
| 行内块 inline-block | (用 CSS 改造) | 排成一行且可设宽高——按钮排排站的过渡方案 |
span { display: block; } /* 行内 → 块级 */
li { display: inline-block; } /* 列表横排 */
a { display: inline-block; padding: 8px 16px; } /* 给链接加可点击的"肉身" */
💡
display是元素的性格开关。现代布局(Flex/Grid,第 06~07 节)本质都是先改变display再谈排列。
五、文档流与两个经典现象
文档流(normal flow):不做任何特殊布局时,元素的默认排版规则——块级从上到下堆,行内从左到右排。
现象一:margin 合并。垂直方向上,相邻两个块级盒子的 margin 会"合并取大"而不是相加:
<p style="margin-bottom: 30px">上段</p>
<p style="margin-top: 20px">下段</p>
<!-- 间距是 30px(取大),不是 50px! -->
现象二:margin 传递。子元素的 margin-top 有时会"穿透"父元素,把父元素一起往下推(父元素没有 border/padding 隔开时)。
这两个现象不是 bug,是规范如此。破解思路:需要精确间距时用 padding 或 Flex 的 gap(第 06 节),少用相邻 margin 对碰。
六、用 DevTools 看盒模型(第 04 模块的技能回收)
选中任何元素 → Styles 面板拉到底 → 彩色盒模型图:
- 蓝色 = content,绿 = padding,黄 = border,橙 = margin
- 间距对不上时看这张图,一眼看出是哪层出了问题
布局调试三连:outline: 1px solid red; 临时加给可疑元素,看它的真实边界在哪。
七、动手跟练:05 · 卡片布局
配套文件:02-web-basics/examples/05-卡片布局.html
步骤:
- Live Server 打开:三张卡片,当前挤在一起很难看
- 按文件里 6 个 TODO 依次修:加 border-box、给卡片 padding、加 margin、水平居中、修 margin 合并、给图片区留白
- 每修一条保存看效果,用 DevTools 盒模型图验证
通关标准:
- 卡片实际宽度 = 设定宽度(border-box 生效)
- 卡片间距均匀且和父容器边界清晰
- 能指着 DevTools 盒模型图说出每层的颜色和数值
八、自测题
- 盒模型四层从内到外依次是什么?哪层用背景色会透出来?(提示:padding 区域)
- 默认
content-box下width: 200px; padding: 10px; border: 2px的盒子实际占多宽? - 为什么全项目要设
box-sizing: border-box? <span>设width: 200px无效,为什么?怎么让它生效?- 相邻两个元素的 margin-bottom: 30px 和 margin-top: 20px,最终间距多少?
参考答案
- content → padding → border → margin;padding 会显示元素自身背景。
- 200 + 10×2 + 2×2 = 224px。
- 让 width 语义稳定(说到即所得),布局不再因 padding/border 意外膨胀。
- span 是行内元素,宽高由内容决定;改
display: inline-block或block后生效。 - 30px(margin 合并取大,不相加)。
九、下一步
单个盒子懂了,接下来解决"一堆盒子怎么排" → 第 06 节:Flex 弹性布局,现代 CSS 布局的主力武器。