05盒模型
浏览器眼里,每个元素都是一个矩形盒子:内容、内边距、边框、外边距四层套娃。 弄懂盒模型,就弄懂了 CSS 布局的一半——为什么 div 设了 width 却「越量越宽」、 为什么两个盒子之间会「神秘合并」,答案全在盒子里。
一、万物皆盒:四层解剖图
从里到外四层:content(内容)→ padding(内边距)→ border(边框)→ margin(外边距)。 padding 是「盒子里面的软垫」,撑大盒子本体的透明区域; margin 是「盒子外面的气场」,负责推开别人,永远透明。
width / height 默认量这里
| 层级 | 名字 | 能设颜色吗 | 占尺寸吗 | 一句话 |
|---|---|---|---|---|
| 第 1 层 | content | —(背景透出) | ✓ | 真正放文字图片的地方 |
| 第 2 层 | padding | ✓(跟背景色) | ✓ | 内容与边框之间的软垫 |
| 第 3 层 | border | ✓ | ✓ | 盒子的实体边 |
| 第 4 层 | margin | ✗ 永远透明 | ✗(只推开别人) | 盒子间的社交距离 |
把四层同时开到一个元素上,看它们各自的「势力范围」:
padding、border、margin 改大,看哪几层跟着变胖背景色铺满到 border 内沿
二、width 到底量到哪:content-box vs border-box
这是盒模型最重要的一课。默认 box-sizing: content-box 下,
width 只量内容区——加上 padding 和 border 后,盒子实际宽度
= width + padding×2 + border×2。border-box 则让 width「一口价包含全部」。
| 值 | 效果 | 使用场景 |
|---|---|---|
| content-box(默认值) | width 只量内容区,padding / border 额外加上去 | 兼容老代码;需要精确控制「内容净尺寸」时 |
| border-box | width 一口价:内容 + padding + border 全包 | 现代项目标配,重置样式里全站开启 |
.cb 的 border 改成 20px,左边继续长胖、右边纹丝不动写着 160
实际 172px
写着 160
实际 160px
* { box-sizing: border-box }?
因为算加法(content-box)反人类——设计稿量出来 200px,你就写 200px,
padding、border 都从里面扣,不用再拿计算器。三、padding:盒内软垫的四种写法
和 margin 语法完全一致:1~4 个值按上 → 右 → 下 → 左顺时针转一圈, 缺的值「对面补齐」。
| 写法 | 展开含义 | 记忆 |
|---|---|---|
| padding: 8px | 上 8、右 8、下 8、左 8 | 一个值管四面 |
| padding: 8px 24px | 上下 8,左右 24 | 先上下、后左右 |
| padding: 4px 8px 28px | 上 4,左右 8,下 28 | 缺的「左」找对面的「右」补齐 |
| padding: 4px 8px 6px 12px | 上 4、右 8、下 6、左 12 | 顺时针转一整圈 |
| padding-left: 20px | 只设一面 | 微调时用单边属性 |
| margin: 0 auto | 上下 0,左右自动平分(仅 margin 有 auto) | 块级水平居中,第五节细讲 |
.pd-c 的第 3 个值改成 40px,看底部软垫变厚四边全 8
上下8 左右24
上4 左右8 下28
padding: 12px 32px,比写死 width/height 更灵活——
文字多长按钮就多长,中英文都适用。四、margin:外边距与著名的「合并」现象
margin 推开相邻元素。但有个垂直方向的经典陷阱: 上下两个块级元素的 margin-bottom 和 margin-top 不会叠加,取大的那个—— 这叫「外边距合并」。左右方向没有这个现象。
margin-top 改成 20px——间距不变,因为 40 更大| 情形 | 合并结果 | 规避办法 |
|---|---|---|
| 相邻兄弟:A 的 margin-bottom 遇上 B 的 margin-top | 取两者较大值,不相加 | 团队约定统一只写 margin-bottom,最省心 |
| 父子首尾:父元素与第一个 / 最后一个孩子的上 / 下 margin | 合并取大,看起来像「父被孩子的 margin 顶跑」 | 父元素加 padding / border 挡住,或加 overflow: hidden 触发 BFC |
| 空块自身:没有内容、没有 padding / border 的空元素 | 它自己的 margin-top 和 margin-bottom 也会合并取大 | 别用空 div 撑间距,改用 padding 或固定高度 |
| 不合并的:左右方向、行内元素、flex / grid 项目 | 正常相加 | — |
overflow: hidden(触发 BFC)、
父元素加 padding/border 挡住、或干脆「间距只写在一侧」——
实战中团队约定统一只用 margin-bottom 最省心。五、margin auto:块级盒子水平居中
给有宽度的块级元素写 margin: 0 auto,左右 auto 会平分剩余空间,
盒子就居中了。注意两个前提:盒子必须有 width、必须是块级元素。
width 那行删掉,盒子立刻铺满失去居中——前提一不成立margin: 0 auto 只能水平居中;垂直居中它无能为力
(垂直方向的 auto 算出来是 0)。想上下也居中,要用 flex——布局模块见。六、border:三件套 width / style / color
border 必须三个属性齐活才显示,其中style 是灵魂—— 不写 style,width 写 100px 也是白搭。(上一章已逐个属性细讲,这里看它们在盒子上的表现。)
.bd-one 的 border-bottom 改成 border-top,看分隔线跑到上面border-top / right / bottom / left 各自的三件套随便组合。
透明边框 border: 1px solid transparent 还能用来「占位防抖动」。七、outline:不占空间的描边
outline 长得像 border,但不占布局空间: 加 10px 的 outline,盒子纹丝不动;加 10px 的 border,盒子立刻被撑大。 它最著名的舞台是键盘聚焦时的焦点圈。
outline-offset 改成 8px,看空隙变大outline: none 又不给替代样式——
键盘用户将完全迷失在你的页面里。要么留着,要么换成明显的自定义焦点样式。八、在 DevTools 里「看见」盒模型
F12 → Elements → 选中元素 → 右下角 Styles 面板下方,有一张彩色盒模型图: 橙黄=margin、绿黄=border、绿=padding、蓝=content,鼠标悬停对应区域, 页面上的盒子会同步高亮。调间距时改这里的数字,所见即所得。
.dt-mid 的 border 改成 12px,看金色边框层变厚九、本章小结
- 四层套娃:content → padding(有背景、占位)→ border → margin(透明、推开别人)。
- box-sizing: border-box 让 width 一口价;项目开头必写
* { box-sizing: border-box }。 - padding/margin 一到四个值顺时针展开:上右下左,缺的找对面补齐。
- 垂直 margin 相邻会合并取大值;防合并用 BFC、挡板或统一单侧。
margin: 0 auto水平居中的前提:块级 + 有 width。- border 三件套 width/style/color,style 不写全白搭;单边 border 是分隔线神器。
- outline 不占空间,是焦点圈专用;去掉焦点圈必须给替代方案。
- DevTools 盒模型图是调间距的「透视眼」,四色分区所见即所得。
margin: 0 auto 居中,中间用 margin-bottom 控制间距。
再 F12 打开盒模型图验证你算的数字。