CSS 盒模型
盒模型是 CSS 布局的基础,每个 HTML 元素都被看作一个矩形的"盒子",由内容、内边距、边框和外边距组成。
盒模型概述
盒子的组成
一个完整的 CSS 盒子由以下部分组成(从内到外):
| 部分 | 说明 |
|---|---|
| 内容 (Content) | 元素的实际内容,如文本、图片 |
| 内边距 (Padding) | 内容和边框之间的空间 |
| 边框 (Border) | 围绕内容和内边距的边界 |
| 外边距 (Margin) | 边框外部的空间 |
可视化图示:
┌─────────────────────────────────────┐
│ margin │
│ ┌───────────────────────────────┐ │
│ │ border │ │
│ │ ┌───────────────────────────┐ │ │
│ │ │ padding │ │ │
│ │ │ ┌─────────────────────┐ │ │ │
│ │ │ │ content │ │ │ │
│ │ │ └─────────────────────┘ │ │ │
│ │ └───────────────────────────┘ │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
简单示例
<div class="box">内容区域</div>
.box {
width: 200px;
padding: 20px;
border: 5px solid #3498db;
margin: 10px;
}
效果预览: 此盒子应用了 width: 200px, padding: 20px, border: 5px solid #3498db, margin: 10px。
盒模型计算
content-box(默认)
当使用默认的 content-box 时:
元素总宽度 = width(内容)+ padding(左右)+ border(左右)+ margin(左右)
.box {
width: 200px;
padding: 20px;
border: 5px solid #3498db;
/*
* 总宽度 = 200 + 40 + 10 = 250px
* height 同理
*/
}
border-box(推荐)
使用 border-box 时,宽度包含 padding 和 border:
元素总宽度 = width = 内容 + padding + border
.box {
width: 200px;
padding: 20px;
border: 5px solid #3498db;
box-sizing: border-box;
/*
* 内容区宽度 = 200 - 40 - 10 = 150px
* 总宽度始终为 200px
*/
}
对比图示:
content-box(默认): 元素宽度 = 内容宽度 + padding + border,总宽度为 250px(200 + 40 + 10)
border-box(推荐): 元素宽度 = 200px,内容区自动缩小以适应 padding 和 border
box-sizing 属性
基本用法
/* 默认:内容盒模型 */
box-sizing: content-box;
/* 推荐:边框盒模型 */
box-sizing: border-box;
全局设置
/* 推荐在 CSS 开头设置 */
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
box-sizing: border-box; /* 可选:让 body 也使用 border-box */
}
最佳实践
几乎所有现代项目都推荐使用 border-box,因为它让尺寸计算更加直观和简单。
内边距 padding
语法
/* 所有边相同 */
padding: 20px;
/* 上下 左右 */
padding: 10px 20px;
/* 上 左右 下 */
padding: 10px 20px 15px;
/* 上 右 下 左(顺时针) */
padding: 10px 15px 20px 25px;
/* 单独设置 */
padding-top: 10px;
padding-right: 15px;
padding-bottom: 20px;
padding-left: 25px;
效果示例
不同 padding 值的视觉效果:
padding: 10px- 紧凑的内边距padding: 20px- 中等内边距padding: 30px- 宽松的内边距
外边距 margin
语法
/* 所有边相同 */
margin: 20px;
/* 上下 左右 */
margin: 10px 20px;
/* 上 左右 下 */
margin: 10px 20px 15px;
/* 上 右 下 左 */
margin: 10px 15px 20px 25px;
/* 单独设置 */
margin-top: 10px;
margin-right: 15px;
margin-bottom: 20px;
margin-left: 25px;
居中技巧
/* 水平居中块级元素 */
.container {
width: 1000px;
margin: 0 auto; /* 上下0,左右自动 */
}
/* 垂直居中需要其他方法 */
外边距折叠
垂直外边距会折叠:
<div class="box1">Box 1</div>
<div class="box2">Box 2</div>
.box1 { margin-bottom: 30px; }
.box2 { margin-top: 20px; }
实际间距 = 30px(两者中较大的那个),不是 50px
当两个相邻元素分别设置 margin-bottom: 30px 和 margin-top: 20px 时,外边距会发生折叠,实际间距取较大值 30px。
负外边距
/* 负外边距可以让元素移动 */
.negative-margin {
margin-left: -20px; /* 向左移动 */
}
/* 常用技巧:消除最后一项的 margin */
.grid {
margin-right: -10px; /* 父容器用负 margin */
}
.grid-item {
margin-right: 10px; /* 子项用正 margin 抵消 */
}
边框 border
边框属性
/* 边框宽度 */
border-width: 1px;
border-top-width: 2px;
/* 边框样式 */
border-style: solid;
border-top-style: dashed;
/* 边框颜色 */
border-color: #333;
border-left-color: red;
/* 边框简写 */
border: 1px solid #333;
border-top: 2px dashed red;
边框样式
| 值 | 效果 |
|---|---|
solid | 实线边框 |
dashed | 虚线边框 |
dotted | 点线边框 |
double | 双线边框 |
groove | 3D 凹槽效果 |
ridge | 3D 凸脊效果 |
inset | 3D 凹入效果 |
outset | 3D 凸出效果 |
效果预览: 不同边框样式的视觉效果,从左到右依次为 solid、dashed、dotted、double。
圆角 border-radius
/* 所有角相同 */
border-radius: 5px;
/* 椭圆角 */
border-radius: 10px 20px;
/* 单独设置 */
border-radius: 5px 10px 15px 20px;
/* 圆形 */
border-radius: 50%;
border-radius: 999px;
/* 单独角 */
border-top-left-radius: 5px;
border-top-right-radius: 10px;
border-bottom-right-radius: 15px;
border-bottom-left-radius: 20px;
效果预览: 不同 border-radius 值的圆角效果:
- 默认(无圆角)
- border-radius: 5px - 小圆角
- border-radius: 10px - 中等圆角
- border-radius: 50% - 圆形
- border-radius: 5px 15px 25px 35px - 不规则圆角
盒阴影 box-shadow
语法
box-shadow: h-shadow v-shadow blur spread color inset;
| 参数 | 说明 |
|---|---|
h-shadow | 水平偏移(必需) |
v-shadow | 垂直偏移(必需) |
blur | 模糊距离 |
spread | 阴影尺寸 |
color | 阴影颜色 |
inset | 内阴影(可选) |
示例
/* 基础阴影 */
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
/* 大阴影 */
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
/* 内阴影 */
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
/* 多重阴影 */
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1),
0 4px 8px rgba(0, 0, 0, 0.1);
效果预览: 不同 box-shadow 效果:
- 基础阴影
2px 2px 5px rgba(0,0,0,0.3)- 轻柔的投影 - 大阴影
0 10px 25px rgba(0,0,0,0.15)- 弹出层效果 - 内阴影
inset 0 2px 8px rgba(0,0,0,0.2)- 凹陷效果
尺寸计算实战
场景1:固定宽度卡片
/* content-box - 需要手动计算 */
.card {
width: 300px;
padding: 20px;
border: 1px solid #ddd;
/* 内容区实际宽度 = 300 - 40 - 2 = 258px */
}
/* border-box - 更简单 */
.card {
width: 300px;
padding: 20px;
border: 1px solid #ddd;
box-sizing: border-box;
/* 内容区实际宽度 = 300 - 40 - 2 = 258px */
}
场景2:百分比宽度 + 内边距
/* content-box - 超出容器 */
.parent {
width: 100%;
}
.child {
width: 100%; /* 实际 = 100% + 40px */
padding: 20px;
}
/* border-box - 不超出 */
.child {
width: 100%;
padding: 20px;
box-sizing: border-box; /* 实际 = 100%,内边距向内 */
}
场景3:网格布局
.container {
display: flex;
gap: 20px;
}
.item {
flex: 1;
padding: 20px;
border: 1px solid #ddd;
box-sizing: border-box; /* 关键! */
}
实用技巧
1. CSS Reset
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
2. 卡片组件
.card {
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border: 1px solid #e8e8e8;
}
.card:hover {
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}
3. 按钮样式
.button {
display: inline-block;
padding: 10px 20px;
border: none;
border-radius: 4px;
background: #3498db;
color: white;
cursor: pointer;
box-sizing: border-box;
}
.button:hover {
background: #2980b9;
}
4. 响应式容器
.container {
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
box-sizing: border-box;
}
5. 图片自适应
img {
max-width: 100%;
height: auto;
display: block; /* 消除底部空白 */
}
小结
本章学习了:
- 盒模型组成:内容、内边距、边框、外边距
- box-sizing:content-box 和 border-box
- padding 属性:内边距的设置
- margin 属性:外边距和折叠现象
- border 属性:边框样式和圆角
- box-shadow:阴影效果
- 尺寸计算:实际宽度和高度的算法
练习
- 创建三个不同内边距的盒子,直观感受 padding
- 理解 margin 折叠现象
- 使用 border-box 实现一个卡片组件
- 创建一个带阴影的按钮效果
- 计算一个 width: 200px, padding: 20px, border: 2px 的元素实际宽度