布局:盒模型、Flexbox 与 Grid — 从「装饰单件」到「摆放全局」
布局:盒模型、Flexbox 与 Grid — 从「装饰单件」到「摆放全局」
这一章讲三件事: 浏览器把每个元素都当成一个盒子,盒子从内到外分四层, 你平时调的一切间距都是这四层在动;
display属性决定元素是「独占一行」还是「挨着排」; 现代布局只有两件工具——Flexbox 管一行/一列,Grid 管一张二维表。 读完你能做出横排卡片、左右分栏、三列网格这些「看起来像真网站」的布局。 需要的基础:会写规则、会选类(02 章)。
1. 这一章讲什么
前面四章,你一直在装饰单个盒子;这一章解决「一群盒子怎么摆」—— 网页设计一半以上的工夫在布局。它在全书链条的位置:第 ⑤ 级台阶,也是全书最厚的一章。 盒模型是后面一切布局概念的地基;Flexbox 和 Grid 是今天写网页真正在用的两件工具。 (书里那句「Web design isn't just about colors and fonts — it's also about how things are arranged.」 就是本章的立论1。)
2. 顶层全景:先想盒子,再选工具
第一步:盒模型 —— 每个元素都是盒子,四层从内到外:
内容 → 内边距(padding)→ 边框(border)→ 外边距(margin)
│
第二步:display —— 盒子默认怎么排:独占一行(block)/ 挨着排(inline)
│
第三步:选工具 ——
一行或一列内的对齐分布 → Flexbox(display: flex)
二维的行列表格 → Grid(display: grid,1fr 按份分)
图说:盒模型回答「间距从哪来」,display 回答「盒子默认怎么站」,
Flexbox/Grid 回答「一群盒子怎么排」。三层问题,别混。3. 核心原理
盒模型:一切间距现象的统一解释
每个 HTML 元素,浏览器都当成一个矩形盒子——文字也不例外。 这是本章第一句话, 也是全书最值钱的一个模型2。盒子从内到外分四层:
| 层 | 名字 | 位置 | 管什么 |
|---|---|---|---|
| 1 | 内容(content) | 最里 | 元素的真身:文字、图片 |
| 2 | 内边距(padding) | 内容和边框之间 | 往里撑空间,让内容不贴边 |
| 3 | 边框(border) | 内边距外面 | 那条线本身(第 04 章玩过) |
| 4 | 外边距(margin) | 边框外面 | 往外推别人,把元素和邻居隔开 |
一个具体例子把四层同时点亮3:
.box {
margin: 20px;
padding: 10px;
border: 2px solid black;
}浏览器画这个盒子时的完整尺寸账(内容宽 100px 为例):
←───────── 外边距 20px ─────────→
┌──────────────────────────────┐
│ ┌────────────────────────┐ │
边距 │ │ ╔════════════════════╗ │ │ 边距
20px │ │ ║ 内边距 10px ║ │ │ 20px
│ │ ║ ┌────────────────┐ ║ │ │
│ │ ║ │ 内容 100px │ ║ │ │
│ │ ║ └────────────────┘ ║ │ │
│ │ ╚════════════════════╝ │ │
│ └────────────────────────┘ │
└──────────────────────────────┘
盒子实际占地(宽)= 20 + 2 + 10 + 100 + 10 + 2 + 20 = 164px
(100px 内容宽是假设值,为演示编的;四层结构与原书一致)这就是「为什么我给元素设了 width: 100px,它却占了 164px」的答案—— width 只量内容层,padding、border、margin 各往外再长一圈。 你日后遇到的一切「我设的距离和实际不一样」,九成能在这张四层账上找到答案。
display:盒子默认怎么站队
不是所有盒子天生一样站。display 属性管两件事:占多宽、换不换行。
三种模式,书里逐个给了定义和典型元素4:
① block(块级)——独占一行。 默认占满容器的整个宽度,下一个元素只能换行。
<div>、<h1>、<p> 天生如此。
② inline(行内)——挨着排,只裹住内容。 宽度就是内容本身多宽,几个行内元素能在同一行里排。
<span>、<a>、<strong> 天生如此。代价书里点得很死:
行内元素的宽高和垂直方向的内边距、外边距都设了不生效——
它的高度由内容(字号、行高)说了算5。
③ inline-block(行内块)——挨着排,但能设宽高。 外形像行内(坐进一行里), 行为像块级(width、height、padding 全能设)。书里的推荐场景:按钮和导航链接6。
一个必须当场点破的口径问题(原书没讲,本书后面要用): 上一节的盒模型算账,是默认口径——
width只量内容。 业界普遍在文件开头统一改成另一种口径(box-sizing: border-box,width量到边框为止), 第 07 章会把它列为初学者必做的第一件事。这里先记住:默认口径下, 盒子的实际占地 = 内容 + 内边距×2 + 边框×2 + 外边距×2。
Flexbox:一维布局的瑞士刀
Flexbox 解决的是这类问题:一行(或一列)里有好几个盒子,怎么对齐、怎么分空当、怎么拉伸。
比如三个卡片要「横排、等宽、间隔均匀」——用前面的知识你得给每个卡片算宽度,屏幕一变就崩;
Flexbox 一句 display: flex 全交给浏览器分7。
用法两步:在容器上开 flex,然后用容器和子项两头的属性指挥。
.container {
display: flex; /* ① 把容器变成 flex 容器 */
flex-direction: row; /* ② 子项横排(默认值;column = 竖排) */
justify-content: space-between; /* ③ 主轴:两端顶格,中间平均分空当 */
align-items: center; /* ④ 交叉轴:垂直方向居中 */
gap: 20px; /* ⑤ 子项之间统一留 20px */
}容器这头四个属性,分工一句话说清:
| 属性 | 管什么 | 常用值 |
|---|---|---|
flex-direction | 排成行还是列 | row(默认)、column |
justify-content | 主轴方向的分布 | flex-start、center、space-between、space-around |
align-items | 交叉轴方向的对齐 | stretch(默认,拉高)、center、flex-start、flex-end |
主轴/交叉轴这组词,解释一句: flex 排成 row 时,主轴 = 横方向、交叉轴 = 竖方向;
换成 column 两者互换。justify-* 家族永远管主轴,align-* 家族永远管交叉轴——
记住这个对应,就不会再把水平居中写成垂直居中。
子项那头的两个常用属性:flex: 1 表示「按 1 份分剩余空间」
(三个子项都写 flex: 1 → 三等分);order: 2 改显示顺序(不用动 HTML)8。
Grid:二维表格,行列一起排
Grid 解决的是更结构化的问题:把页面切成一张行列格子,把内容丢进格里。 如果说 Flexbox 是「一排货架怎么摆」,Grid 就是「整个仓库的货架平面图」, 书里称它为 CSS 里最强大的布局系统9。
.grid {
display: grid; /* ① 把容器变成网格容器 */
grid-template-columns: repeat(3, 1fr); /* ② 三列,每列一样宽 */
gap: 20px; /* ③ 格子之间留 20px */
}两个新词,当场讲清:
1fr= 一份空间(fr 是 fraction,「份」)。repeat(3, 1fr)就是「三列,每列一份,即等宽」。 把可用宽度按份数切,是 Grid 分空间的根本方式10;gap= 格子间距。只留空当、不动格子尺寸,比给每个格子单独加 margin 干净得多。
容器里丢 4 个子项会发生什么? 自动排:第一行填满 3 个,第 4 个掉到第二行——
Grid 默认按行从左往右自动铺,不需要你逐个指定位置11。
想精确摆也可以:grid-column: 1 / 3 表示「从第 1 条列线跨到第 3 条列线」——
即占第 1、2 两列;配合 grid-row 就能让某个元素跨格,杂志式的不对称版面就是这样做的12。
主线例子:两个练习,把三件工具各走一遍
练习一:三卡片横排(Flexbox)。 HTML 一个容器套三个卡片;CSS 三句话:
容器 display: flex; justify-content: space-between; gap: 20px;,
每个卡片 flex: 1; padding: 20px;13。
浏览器排这一行的过程,逐步看:
| 步骤 | 浏览器做的事 | 这一行的状态 |
|---|---|---|
| 1 | 容器声明了 flex → 三个卡片从「各自独占一行」变成「坐进同一行」 | 三张卡片横排,挤在左边 |
| 2 | gap: 20px → 先扣掉两道口子,共 40px | 卡片 1 ‖ 20px ‖ 卡片 2 ‖ 20px ‖ 卡片 3 |
| 3 | 每个卡片 flex: 1 → 剩余宽度按 1:1:1 分(比如行宽 640px:剩 600px,每张 200px) | 三张等宽卡片,空当均匀 |
| 4 | justify-content: space-between 与等分flex同时存在时,空间已被 flex 吃光 → 实际由 gap 的 20px 定间隔 | 三卡片等宽、间隔正好 20px,两端顶格 |
(行宽 640px、每卡 200px 这些数是为演示编的;三卡等宽、间隔均匀这个效果与原书练习一致。)
为什么 Flexbox 这条路有效? 因为你没有给任何卡片写死宽度——
「等宽」是浏览器按 flex: 1 现场算出来的,容器变宽变窄,三份跟着变。这就是「不写死」第一次显出威力(第 06 章把它推到全页面)。
练习二:侧栏 + 正文两栏(Grid)。 grid-template-columns: 1fr 3fr;——
总共 4 份,侧栏 1 份、正文 3 份,正文永远比侧栏宽 3 倍;
间距仍交给 gap: 20px14。
| 内容 | 份数 | 若容器宽 840px(演示数) |
|---|---|---|
侧栏 .sidebar | 1fr | (840 − 20) ÷ 4 × 1 = 205px |
正文 .content | 3fr | (840 − 20) ÷ 4 × 3 = 615px |
为什么用 1fr 而不是写 width: 210px? 因为容器宽度你说了不算(读者屏幕各异),
fr 让浏览器按份额实时算——屏幕宽就一起宽,屏幕窄就一起窄,比例永远是 1:3。
这一个练习,把盒模型(格子内部的 padding)、Grid(行列分份)和「不写死」三条线拧在了一起。
4. 作者的判断与证据
- 判断:「Grid 是 CSS 里最强大的布局系统。」 原文给了依据式的描述: 它让你轻松做二维布局(行和列)、能做杂志页和仪表盘式的不对称版面912。 「最强大」是价值排序——Flexbox 和 Grid 不是新旧替代关系,而是一维/二维的分工(本章要点也这么说15)。
- 判断:inline-block 「很适合按钮和导航链接」。 经验之谈6。 今天实际项目里这类场景更多直接用 flex——属于 2025 年的写法口味,不影响机制理解。
- 判断:「用 gap、padding、margin 把间距收拾干净。」 章末要点之一15—— 三个工具各管一层间距:gap 管子项之间、padding 管内容到边、margin 管盒子到盒子。
- 事实性内容:四层盒模型、三种 display 的行为差异(含行内不能设垂直边距)、 flex/grid 各属性的取值,均可当场验证。
5. 边界与局限
width的默认口径坑没讲。 默认口径(content-box)下width只量内容层, 盒模型算账会随 padding、border 膨胀——初学者最常见的「我设的 100% 怎么就溢出了」就源于此。 原书把它留到了第 07 章的「常见错误」里才给出box-sizing: border-box这个业界通用修法; 我们在 §3 的口径说明里提前点了名(保持原书顺序,但不让读者踩空)。- Flexbox 和 Grid 都只教了子项直接下级。 「容器里的容器里的卡片」这种多层嵌套怎么指挥, 需要嵌套 flex/嵌套 grid 的概念,原书未展开。
space-between与space-around的区别、align-self、order的完整含义,只有一句话。 够用,但读别人的代码遇到时会想查文档。- 响应式的一句都没讲。 本章所有布局在「当前屏幕宽度」上成立; 屏幕一变怎么办,是下一章(media query)的事——原书刻意把两件事分开教。
- 绝对定位(position)整本未出现。 想把元素钉在页面某个坐标(比如悬浮按钮), 这本书从头到尾没教——它在结尾把读者指去了 MDN(第 07 章)。
6. 可带走的
本章主线例子,一行写完: 三个卡片丢进 flex 容器 → 不写任何宽度,
flex: 1 让浏览器现场三等分、gap 留 20px 空当 → 等宽横排;
侧栏加正文丢进 grid 容器 → 1fr 3fr 按四份分 → 正文永远三倍宽。
- 每个元素都是盒子,四层:内容 → padding → border → margin;默认口径下实际占地 = 内容 + 2×(padding+border+margin);
- padding 往里撑,margin 往外推,方向感错了调一天也调不对;
display三模式:block 独占一行、inline 挨着排但垂直尺寸设了不生效、inline-block 兼得;- 一维排布找 Flexbox:容器
display: flex开局,justify-*管主轴、align-*管交叉轴; flex: 1= 按 1 份分剩余空间,几个子项都写就是等分——不写死宽度的第一个武器;- 二维排布找 Grid:
grid-template-columns: repeat(3, 1fr)三列等宽,gap统一格子间距; 1fr= 一份空间,1fr 3fr就是 1:3——比例钉死、绝对尺寸交给浏览器;- 间距三件套分工:gap 管子项间、padding 管内容到边、margin 管盒子到盒子。
7. 原文地图
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| 布局是设计的另一半 | Chapter 5: Layouts with Box Model, Flexbox, and Grid | text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:12(搜「isn’t just about colors」) |
| 每个元素都是盒子 | 同上 | text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:17(搜「Every HTML element is a box」) |
| 四层表(content/padding/border/margin) | 同上 | text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:37(搜「actual text」) · text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:43(搜「separates elements」) |
| 10px 内 / 20px 外的例子 | 同上 | text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:52(搜「inside the border」) |
| display 三模式 | 同上 | text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:59(搜「full width」) · text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:69(搜「width/height/padding/margin」) · text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:82(搜「display: inline-block」) |
| Flexbox 定义与容器属性 | 同上 | text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:86(搜「modern CSS layout tool」) · text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:101(搜「row (default)」) · text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:104(搜「controls horizontal alignment」) |
| 子项属性 flex/order | 同上 | text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:120(搜「controls how much space」) |
| Grid 定义、1fr、自动铺行 | 同上 | text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:157(搜「most powerful layout system」) · text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:176(搜「one fraction」) · text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:189(搜「next row」) |
| 跨列摆放 grid-column | 同上 | text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:199(搜「spans columns」) |
| 练习:三卡片、1fr 3fr | 同上 | text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:136(搜「cards」) · text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:223(搜「1fr 3fr」) · text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:239(搜「3x wider」) |
| 章末要点(Flexbox 一维 / Grid 二维) | 同上 | text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:247(搜「1D layouts」) |
Footnotes
-
出处:「Chapter 5: Layouts with Box Model, Flexbox, and Grid」第 12–14 段(
text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:12,搜「isn’t just about colors」)。原文:「Web design isn’t just about colors and fonts — it’s also about how things are arranged on the page.」 ↩ -
出处:「Chapter 5: Layouts with Box Model, Flexbox, and Grid」第 17–18 段(
text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:17,搜「Every HTML element is a box」)。原文:「Every HTML element is a box — even text! The box model describes how space is structured around elements.」 ↩ -
出处:「Chapter 5: Layouts with Box Model, Flexbox, and Grid」第 35–53 段(
text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:52,搜「inside the border」)。原文:「This creates 10px of space inside the border (padding), and 20px of space outside the border (margin).」164px 的总账是按默认盒模型口径推的(补充计算,不在书里)。 ↩ -
出处:「Chapter 5: Layouts with Box Model, Flexbox, and Grid」第 55–83 段(
text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:59,搜「full width」;:67,搜「as much width as necessary」)。block:「Takes up the full width of the container」「Starts on a new line」;inline:「Only takes up as much width as necessary」「Sits beside other elements」。 ↩ -
出处:「Chapter 5: Layouts with Box Model, Flexbox, and Grid」第 69 段(
text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:69,搜「width/height/padding/margin」)。原文:「You can’t set width/height/padding/margin (only horizontally)」——行内元素垂直方向的尺寸与边距不生效。 ↩ -
出处:「Chapter 5: Layouts with Box Model, Flexbox, and Grid」第 75–83 段(
text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:82,搜「display: inline-block」;:78,搜「buttons and nav links」)。原文:「Like inline (sits in line), but you can set width, height, padding, etc.」「Great for buttons and nav links」。 ↩ ↩2 -
出处:「Chapter 5: Layouts with Box Model, Flexbox, and Grid」第 85–99 段(
text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:86,搜「modern CSS layout tool」;:89,搜「flex container」)。原文:「Flexbox is a modern CSS layout tool that makes it easy to align and space elements in a row or column.」 ↩ -
出处:「Chapter 5: Layouts with Box Model, Flexbox, and Grid」第 108–122 段(
text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:120,搜「controls how much space」;:122,搜「display order」)。原文:「flex — controls how much space the item takes」「order — changes the display order of items」。 ↩ -
出处:「Chapter 5: Layouts with Box Model, Flexbox, and Grid」第 156–157 段(
text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:157,搜「most powerful layout system」)。原文:「CSS Grid is the most powerful layout system in CSS. It lets you create two-dimensional layouts — rows and columns.」 ↩ ↩2 -
出处:「Chapter 5: Layouts with Box Model, Flexbox, and Grid」第 164–178 段(
text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:176,搜「one fraction」;:178,搜「gap adds space」)。原文:「1fr means ‘one fraction of the space’」「gap adds space between items」。 ↩ -
出处:「Chapter 5: Layouts with Box Model, Flexbox, and Grid」第 180–189 段(
text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:189,搜「next row」)。原文:「This will automatically fill the first row with 3 items, and place the 4th item on the next row.」 ↩ -
出处:「Chapter 5: Layouts with Box Model, Flexbox, and Grid」第 191–206 段(
text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:199,搜「spans columns」;:205,搜「asymmetric layouts」)。原文:「grid-column: 1 / 3; /* spans columns 1 and 2 */」;「You can even make asymmetric layouts easily — like magazine pages or dashboards.」 ↩ ↩2 -
出处:「Chapter 5: Layouts with Box Model, Flexbox, and Grid」第 124–154 段(
text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:136,搜「cards」;:154,搜「spaced evenly」)。原文示例:「display: flex; justify-content: space-between; gap: 20px;」加每个卡片的「flex: 1」;「This creates 3 equal cards spaced evenly across the row.」 ↩ -
出处:「Chapter 5: Layouts with Box Model, Flexbox, and Grid」第 208–239 段(
text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:223,搜「1fr 3fr」;:239,搜「3x wider」)。原文:「1fr 3fr means the main content is 3x wider than the sidebar.」840px 容器、205/615px 的换算数是为演示编的。 ↩ -
出处:「Chapter 5: Layouts with Box Model, Flexbox, and Grid」第 241–251 段(
text/06-ch05-chapter-5-layouts-with-box-model-flexbox-and-gri.txt:247,搜「1D layouts」;:251,搜「space things cleanly」)。原文:「Flexbox is great for 1D layouts (rows or columns)」「Grid is perfect for complex 2D layouts with rows and columns」「Use gap, padding, and margin to space things cleanly」。 ↩ ↩2