CSS: CSS 盒模型
盒模型(Box Model)是 CSS 布局的基石。在 CSS 的世界里,每个 HTML 元素都被看作一个矩形的"盒子",这个盒子由内容区域、内边距、边框和外边距组成。
盒模型属性速查表
| 属性 | 常用值 | 作用 |
|---|---|---|
width |
300px, 50%, auto |
内容区域宽度 |
height |
200px, auto |
内容区域高度 |
padding |
20px, 10px 20px, 10px 20px 15px 5px |
内边距(内容到边框的距离) |
border |
2px solid #333 |
边框(宽度+样式+颜色) |
margin |
10px, 20px auto, 0 auto |
外边距(元素到其他元素的距离) |
box-sizing |
content-box(默认), border-box |
宽高的计算范围 |
1. 盒模型的四个部分
从内到外依次是:
graph TB
subgraph "盒模型结构"
M["外边距 (Margin) - 元素与其他元素之间的距离"]
B["边框 (Border) - 包裹内容的边框线"]
P["内边距 (Padding) - 内容与边框之间的留白"]
C["内容区域 (Content) - 文本、图片等实际内容"]
M --> B --> P --> C
end
TEXT
📖 仅展示
┌────────────────────────────────────┐ ← 外边距 (Margin)
│ ┌──────────────────────────────┐ │ ← 边框 (Border)
│ │ ┌────────────────────────┐ │ │ ← 内边距 (Padding)
│ │ │ │ │ │
│ │ │ 内容区域 (Content) │ │ │
│ │ │ │ │ │
│ │ └────────────────────────┘ │ │
│ └──────────────────────────────┘ │
└────────────────────────────────────┘
(1) 1. 内容区域(Content)
元素实际内容的区域,比如文本、图片等。宽度和高度由 width 和 height 属性控制。
(2) 2. 内边距(Padding)
内容区域与边框之间的空间,用于在内容和边框之间创建留白。
▶ 示例
HTML
<style>
.box {
padding: 20px; /* 四边都是20px */
background: #fce4ec;
border: 2px solid #e91e63;
}
</style>
<div class="box">这是一个盒子元素,内边距让内容与边框之间有了20px的留白空间</div>
(3) 3. 边框(Border)
包裹内边距和内容区域的边框线。
▶ 示例
HTML
<style>
.box {
border: 2px solid #333;
padding: 16px;
background: #f9f9f9;
}
</style>
<div class="box">这是一个盒子元素,边框包裹在内边距外侧</div>
(4) 4. 外边距(Margin)
边框与其他元素之间的空间,用于控制元素之间的距离。
▶ 示例
HTML
<style>
.box {
margin: 10px; /* 四边都是10px */
background: #e8f5e9;
border: 1px solid #66bb6a;
padding: 10px;
}
</style>
<div class="box">盒子1 - 有10px外边距</div>
<div class="box">盒子2 - 与盒子1之间有20px间距</div>
<div class="box">盒子3 - 与盒子2之间有20px间距</div>
💡 注意: 块级元素的上下外边距会"合并"(取最大值而非相加),这是CSS的正常行为。左右外边距不会合并。
2. 盒子的实际尺寸
这是最容易搞混的地方——元素的宽度和高度不等于内容区域的宽高。
默认情况下(box-sizing: content-box):
TEXT
📖 仅展示
元素总宽度 = width + padding-left + padding-right + border-left + border-right
元素总高度 = height + padding-top + padding-bottom + border-top + border-bottom
举个例子:
▶ 示例
HTML
<style>
.box {
width: 200px;
height: 100px;
padding: 20px;
border: 2px solid black;
background: #e3f2fd;
text-align: center;
line-height: 1.5;
}
</style>
<div class="box">
内容区域 200×100px<br>
实际渲染 244×144px
</div>
这个盒子的实际渲染尺寸是:
- 总宽度 = 200 + 20×2 + 2×2 = 244px
- 总高度 = 100 + 20×2 + 2×2 = 144px
如果你以为这个盒子只有 200×100,那就错了!很多新手在这上面栽跟头。
3. box-sizing 属性
为了解决上述"实际尺寸比设定大"的问题,CSS3 引入了 box-sizing 属性。
(1) content-box(默认)
width 和 height 只包含内容区域,padding 和 border 不包含在内。这是默认值,也是"坑"的根源。
(2) border-box
width 和 height 包含内容 + padding + border,边框和内边距不会"撑大"元素:
▶ 示例:content-box vs border-box 对比
HTML
<style>
.container {
display: flex;
justify-content: space-around;
}
.box {
width: 300px;
height: 200px;
border: 10px solid indianred;
}
.item {
width: 100%;
background: rgba(49, 115, 187, 0.3);
border: solid #5B6DCD 10px;
padding: 15px;
}
.s1 { box-sizing: content-box; }
.s2 { box-sizing: border-box; }
</style>
<div class="container">
<div class="box">
<h3>content-box(默认)</h3>
<div class="item s1">width: 100% + padding + border = 超出父容器</div>
</div>
<div class="box">
<h3>border-box</h3>
<div class="item s2">width: 100% 包含 padding + border = 正好</div>
</div>
</div>
💡 对比效果: content-box 模式下,子元素会超出父容器;border-box 模式下,子元素正好填满父容器。这就是为什么现代项目都推荐全局设置
box-sizing: border-box。
HTML
<style>
.box {
box-sizing: border-box;
/* 盒模型计算方式 */
width: 200px;
padding: 20px;
border: 2px solid black;
/* 实际宽度仍然是 200px */
}
</style>
<div class="box">这是一个盒子元素,用于展示盒模型相关样式效果</div>
<span class="border-demo">实线边框</span>
使用 border-box 后,内容区域会被"压缩",但总尺寸不变。这种方式更符合直觉,也是目前主流项目中的推荐做法。
(3) 全局设置 border-box
很多项目会在 reset 中统一设置:
▶ 示例
HTML
<style>
*, *::before, *::after {
box-sizing: border-box;
}
</style>
<div class="box-demo">演示盒子</div>
4. 盒模型的调试
使用浏览器开发者工具可以直观地查看盒模型:
💡 调试技巧: 在浏览器按 F12 打开开发者工具,Elements 面板的 Computed 选项卡里可以直观地看到每个元素的 content、padding、border、margin——这是排查布局问题最快的方法。
- 在页面中右键点击元素,选择"检查"
- 在 Elements 面板中选中元素
- 切换到 Computed(计算后)或 Layout(布局)面板
- 你会看到一个盒模型图示,显示 content、padding、border、margin 各是多少
5. 盒模型对不同元素的差异
- 块级元素:默认宽度是父容器的 100%,高度由内容决定
- 行内元素:不接受 width 和 height,padding/margin 只在水平方向有效
- 行内块元素:可以设置宽高,但不会独占一行
❓ 常见问题
Q content-box 和 border-box 到底选哪个?
A 绝大多数项目都选
border-box。设置为 border-box 后,padding 和 border 不会撑大元素的宽高,布局计算更直观。很多框架(Bootstrap、Tailwind)都是全局设置 border-box。除非有特殊需求,否则不要用默认的 content-box。Q 怎么在浏览器里看盒模型?
A 按 F12 打开开发者工具,在 Elements 面板中选中一个元素,右侧的 Computed 或 Styles 面板会显示盒模型的四层结构(content/padding/border/margin)。这是排查布局问题最快的方法,强烈建议养成习惯。
Q margin 和 padding 都能产生间距,什么时候用哪个?
A 记住一个原则:background 是否应该覆盖这个区域?如果用 padding,背景色会覆盖它;如果用 margin,不会。简单说,元素内部的间距用 padding,元素外部的间距用 margin。
📖 小节
- 盒模型是 CSS 最基础也最重要的概念
- 理解 content、padding、border、margin 四层结构,以及
box-sizing对尺寸计算的影响,是写出可靠布局的前提 - 建议在项目开始时就把
box-sizing: border-box设置为全局默认值,能省去很多尺寸计算的麻烦
📝 作业
基础题
- 创建一个 200×200 的盒子,设置 padding 为 30px,border 为 5px solid。使用浏览器的开发者工具查看它的实际渲染尺寸,验证盒模型计算公式。
- 复制上面的盒子,添加
box-sizing: border-box,观察实际尺寸的变化,对比与上题的区别。
进阶题
- 创建一个包含两个并列盒子的页面,调整它们的 margin 值,观察"外边距合并"现象(块级元素上下 margin 会取最大值而非相加)。
- 使用
border-box完成一个"左右两栏各占 50% 宽度且中间有 20px 间距"的布局。
挑战题
- 创建一个卡片组件,要求:
- 卡片宽度固定 300px
- 内边距 20px
- 边框 1px solid #ddd
- 圆角 8px
- 使用
border-box确保总宽度始终为 300px
- 创建一个表单布局,使用盒模型计算确保输入框和按钮完美对齐。