返回笔记列表
01 · NOTES / WebGIS 开发

第 05 节 · 盒模型与布局流

2026 年 9 月 1 日

第 05 节 · 盒模型与布局流

📌 版本信息:基于 CSS 现行规范(box-sizing 为稳定特性;2026-08-29 核对) 📚 来源:MDN 盒模型MDN 常规流

一、这一节的目标

  1. 精通盒模型四层结构:content / padding / border / margin
  2. 会用 DevTools 的盒模型图调试间距问题
  3. 分清块级元素与行内元素的排版规则
  4. 理解文档流(normal flow)与 margin 合并现象
  5. 会用 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

步骤:

  1. Live Server 打开:三张卡片,当前挤在一起很难看
  2. 按文件里 6 个 TODO 依次修:加 border-box、给卡片 padding、加 margin、水平居中、修 margin 合并、给图片区留白
  3. 每修一条保存看效果,用 DevTools 盒模型图验证

通关标准:

  • 卡片实际宽度 = 设定宽度(border-box 生效)
  • 卡片间距均匀且和父容器边界清晰
  • 能指着 DevTools 盒模型图说出每层的颜色和数值

八、自测题

  1. 盒模型四层从内到外依次是什么?哪层用背景色会透出来?(提示:padding 区域)
  2. 默认 content-boxwidth: 200px; padding: 10px; border: 2px 的盒子实际占多宽?
  3. 为什么全项目要设 box-sizing: border-box
  4. <span>width: 200px 无效,为什么?怎么让它生效?
  5. 相邻两个元素的 margin-bottom: 30px 和 margin-top: 20px,最终间距多少?

参考答案

  1. content → padding → border → margin;padding 会显示元素自身背景。
  2. 200 + 10×2 + 2×2 = 224px。
  3. 让 width 语义稳定(说到即所得),布局不再因 padding/border 意外膨胀。
  4. span 是行内元素,宽高由内容决定;改 display: inline-blockblock 后生效。
  5. 30px(margin 合并取大,不相加)。

九、下一步

单个盒子懂了,接下来解决"一堆盒子怎么排" → 第 06 节:Flex 弹性布局,现代 CSS 布局的主力武器。

TAGSweb