CSS基础-盒模型与布局基础
盒模型是CSS布局的核心概念,理解盒模型和基础布局属性是掌握CSS的关键。
本文将深入讲解CSS盒模型、display、position 等核心布局属性,以及它们在实际开发中的应用。
# 一、CSS盒模型
# 1.1 盒模型组成
每个HTML元素都可以看作一个矩形盒子,由四个部分组成:
┌─────────────────────────────────────┐
│ margin (外边距) │
│ ┌───────────────────────────────┐ │
│ │ border (边框) │ │
│ │ ┌─────────────────────────┐ │ │
│ │ │ padding (内边距) │ │ │
│ │ │ ┌───────────────────┐ │ │ │
│ │ │ │ content (内容) │ │ │ │
│ │ │ │ width x height │ │ │ │
│ │ │ └───────────────────┘ │ │ │
│ │ └─────────────────────────┘ │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
- content (内容区):显示文本、图片等内容
- padding (内边距):内容与边框之间的空间
- border (边框):围绕内边距的边框
- margin (外边距):元素与其他元素之间的空间
# 1.2 标准盒模型 vs 怪异盒模型
# 标准盒模型 (content-box)
.box {
box-sizing: content-box; /* 默认值 */
width: 200px;
height: 100px;
padding: 20px;
border: 5px solid #333;
margin: 10px;
}
计算方式:
- 内容宽度:200px (width设置的值)
- 实际占用宽度:200px (width) + 40px (padding左右) + 10px (border左右) = 250px
- 包含margin的总宽度:250px + 20px (margin左右) = 270px
实际占用空间 = width + padding + border
总空间 = width + padding + border + margin
# 怪异盒模型 (border-box)
.box {
box-sizing: border-box; /* 推荐使用 */
width: 200px;
height: 100px;
padding: 20px;
border: 5px solid #333;
margin: 10px;
}
计算方式:
- 实际占用宽度:200px (width设置的值已包含padding和border)
- 内容宽度:200px - 40px (padding) - 10px (border) = 150px
- 包含margin的总宽度:200px + 20px (margin) = 220px
width = content + padding + border
实际内容宽度 = width - padding - border
# 最佳实践
/* 全局设置为 border-box,更符合直觉 */
*, *::before, *::after {
box-sizing: border-box;
}
为什么推荐 border-box?
- 设置的
width就是元素的实际宽度,更直观 - 添加
padding或border不会改变元素宽度 - 更容易计算和控制布局
# 1.3 外边距合并 (Margin Collapse)
外边距合并是指相邻元素的垂直外边距会合并为一个外边距。
# 相邻兄弟元素
<div class="box1">Box 1</div>
<div class="box2">Box 2</div>
.box1 {
margin-bottom: 30px;
}
.box2 {
margin-top: 20px;
}
/* 实际间距:30px (取较大值),而不是 50px */
# 父子元素
<div class="parent">
<div class="child">Child</div>
</div>
.parent {
margin-top: 20px;
}
.child {
margin-top: 30px;
}
/* parent 的实际 margin-top:30px (与子元素合并) */
如何避免外边距合并?
/* 方法1:给父元素添加 border 或 padding */
.parent {
padding-top: 1px; /* 或 border-top: 1px solid transparent; */
}
/* 方法2:使用 overflow */
.parent {
overflow: hidden; /* 或 auto */
}
/* 方法3:使用 Flexbox 或 Grid */
.parent {
display: flex;
flex-direction: column;
}
# 空元素的外边距合并
.empty {
margin-top: 20px;
margin-bottom: 30px;
}
/* 自身的上下margin会合并为 30px */
# 1.4 盒模型相关属性
# width 和 height
.box {
/* 固定尺寸 */
width: 200px;
height: 100px;
/* 百分比(相对于父元素) */
width: 50%;
height: 100%;
/* 最小/最大限制 */
min-width: 100px;
max-width: 500px;
min-height: 50px;
max-height: 300px;
/* 自动(默认值) */
width: auto;
height: auto;
}
# padding (内边距)
.box {
/* 四个方向相同 */
padding: 20px;
/* 上下 | 左右 */
padding: 10px 20px;
/* 上 | 左右 | 下 */
padding: 10px 20px 30px;
/* 上 | 右 | 下 | 左 (顺时针) */
padding: 10px 20px 30px 40px;
/* 单独设置 */
padding-top: 10px;
padding-right: 20px;
padding-bottom: 30px;
padding-left: 40px;
}
# margin (外边距)
.box {
/* 语法同 padding */
margin: 20px;
margin: 10px 20px;
margin: 10px 20px 30px 40px;
/* 水平居中 */
margin: 0 auto;
/* 负边距 */
margin-top: -10px; /* 向上移动 */
margin-left: -20px; /* 向左移动 */
}
# border (边框)
.box {
/* 简写:宽度 样式 颜色 */
border: 2px solid #333;
/* 单独设置 */
border-width: 2px;
border-style: solid; /* none | solid | dashed | dotted | double */
border-color: #333;
/* 单边设置 */
border-top: 1px solid red;
border-right: 2px dashed blue;
border-bottom: 3px dotted green;
border-left: 4px double orange;
/* 圆角 */
border-radius: 5px;
border-radius: 10px 20px; /* 左上右下 | 右上左下 */
border-radius: 10px 20px 30px 40px; /* 左上 | 右上 | 右下 | 左下 */
/* 圆形 */
border-radius: 50%;
}
# 二、display 属性
display 属性决定元素的显示类型和布局方式。
# 2.1 block (块级元素)
div, p, h1-h6, ul, ol, li, header, footer, section {
display: block; /* 默认值 */
}
特点:
- 独占一行
- 可以设置
width、height - 默认宽度为父元素的100%
- 可以设置
margin、padding的所有方向
.block {
display: block;
width: 300px;
height: 100px;
margin: 20px;
padding: 10px;
background-color: #e0e0e0;
}
# 2.2 inline (行内元素)
span, a, strong, em, img, input, label {
display: inline; /* 默认值 */
}
特点:
- 不独占一行,多个行内元素在同一行显示
- 不能设置
width、height - 宽高由内容决定
- 只能设置水平方向的
margin、padding - 垂直方向的
margin、padding不会影响布局(但会显示)
.inline {
display: inline;
/* width: 200px; 无效 */
/* height: 100px; 无效 */
margin: 0 10px; /* 只有左右有效 */
padding: 5px 15px; /* 上下会显示但不影响布局 */
background-color: #ffeb3b;
}
# 2.3 inline-block (行内块元素)
.inline-block {
display: inline-block;
}
特点:
- 不独占一行(类似inline)
- 可以设置
width、height(类似block) - 可以设置所有方向的
margin、padding - 常见问题:元素之间会有空隙(HTML空白符导致)
.btn {
display: inline-block;
width: 120px;
height: 40px;
padding: 10px 20px;
margin: 0 5px;
text-align: center;
line-height: 20px;
background-color: #007bff;
color: white;
border-radius: 4px;
}
消除inline-block元素间隙:
/* 方法1:父元素设置 font-size: 0 */
.parent {
font-size: 0;
}
.inline-block {
font-size: 16px; /* 恢复字体大小 */
}
/* 方法2:使用负margin */
.inline-block {
margin-right: -4px;
}
/* 方法3:HTML不换行(不推荐) */
# 2.4 none (隐藏元素)
.hidden {
display: none; /* 元素不显示,且不占据空间 */
}
对比 visibility: hidden:
/* display: none - 不显示,不占空间 */
.display-none {
display: none;
}
/* visibility: hidden - 不显示,但占据空间 */
.visibility-hidden {
visibility: hidden;
}
/* opacity: 0 - 不可见,但占据空间且可交互 */
.opacity-zero {
opacity: 0;
}
# 2.5 flex 和 grid
/* Flexbox布局(后续文章详细介绍) */
.flex-container {
display: flex;
}
/* Grid布局(后续文章详细介绍) */
.grid-container {
display: grid;
}
# 2.6 table 相关
.table {
display: table;
}
.table-row {
display: table-row;
}
.table-cell {
display: table-cell;
vertical-align: middle; /* 垂直居中 */
}
# 三、position 属性
position 属性指定元素的定位方式。
# 3.1 static (静态定位)
div {
position: static; /* 默认值 */
}
特点:
- 正常文档流
top、right、bottom、left、z-index属性无效- 不会创建新的定位上下文
# 3.2 relative (相对定位)
.relative {
position: relative;
top: 20px; /* 向下偏移20px */
left: 30px; /* 向右偏移30px */
}
特点:
- 相对于元素原本位置偏移
- 原本位置仍然占据空间
- 不影响其他元素布局
- 创建新的定位上下文(子元素absolute定位的参考)
<div class="box">
<div class="relative">相对定位</div>
<div>普通元素</div>
</div>
.relative {
position: relative;
top: 20px;
left: 20px;
background-color: #ffeb3b;
}
/* "普通元素"会出现在.relative原本位置的下方 */
# 3.3 absolute (绝对定位)
.absolute {
position: absolute;
top: 20px;
right: 30px;
}
特点:
- 相对于最近的非static定位祖先元素定位
- 如果没有定位祖先,则相对于初始包含块(通常是
<html>) - 脱离文档流,不占据空间
- 其他元素会当它不存在
<div class="parent">
<div class="absolute">绝对定位</div>
</div>
.parent {
position: relative; /* 为子元素提供定位参考 */
width: 300px;
height: 200px;
background-color: #e0e0e0;
}
.absolute {
position: absolute;
top: 20px; /* 距离parent顶部20px */
right: 20px; /* 距离parent右边20px */
width: 100px;
height: 50px;
background-color: #ff5722;
}
常见应用场景:
/* 1. 右上角徽章 */
.badge {
position: absolute;
top: -5px;
right: -5px;
}
/* 2. 遮罩层 */
.overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
}
/* 3. 水平垂直居中 */
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
# 3.4 fixed (固定定位)
.fixed {
position: fixed;
top: 0;
right: 0;
}
特点:
- 相对于**浏览器窗口(视口)**定位
- 脱离文档流
- 滚动页面时,元素位置不变
- 始终显示在视口的固定位置
/* 固定头部 */
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 60px;
background-color: #333;
z-index: 1000;
}
/* 返回顶部按钮 */
.back-to-top {
position: fixed;
bottom: 20px;
right: 20px;
width: 50px;
height: 50px;
background-color: #007bff;
border-radius: 50%;
}
注意事项:
/* 使用fixed时,记得给后续内容留出空间 */
body {
padding-top: 60px; /* header的高度 */
}
# 3.5 sticky (粘性定位)
.sticky {
position: sticky;
top: 0;
}
特点:
- 结合了
relative和fixed的特性 - 在阈值范围内表现为
relative - 超过阈值后表现为
fixed - 不脱离文档流
/* 吸顶导航 */
.nav {
position: sticky;
top: 0;
background-color: white;
z-index: 100;
}
/* 表格标题行固定 */
thead th {
position: sticky;
top: 0;
background-color: #f5f5f5;
}
兼容性注意:
- 现代浏览器支持良好
- 注意父元素不能有
overflow: hidden等属性 - 必须指定
top、bottom、left或right之一
# 3.6 定位属性对比
| 属性 | 是否脱离文档流 | 定位参考 | 是否占据空间 | 常见用途 |
|---|---|---|---|---|
| static | ❌ | 正常流 | ✅ | 默认值 |
| relative | ❌ | 自身原位置 | ✅ | 微调位置、定位上下文 |
| absolute | ✅ | 定位祖先 | ❌ | 弹窗、遮罩、徽章 |
| fixed | ✅ | 视口 | ❌ | 固定头部、返回顶部 |
| sticky | ❌ | 视口+正常流 | ✅ | 吸顶导航、表格标题 |
# 3.7 z-index (层叠顺序)
.element {
position: relative; /* 或 absolute、fixed、sticky */
z-index: 10;
}
规则:
- 只对定位元素有效(position 非 static)
- 数值越大,层级越高
- 相同z-index时,后面的元素覆盖前面的
- 创建层叠上下文
/* 示例 */
.modal-overlay {
position: fixed;
z-index: 1000;
}
.modal-content {
position: relative;
z-index: 1001;
}
.tooltip {
position: absolute;
z-index: 2000;
}
层叠上下文:
/* 父元素的z-index会影响子元素 */
.parent {
position: relative;
z-index: 1;
}
.child {
position: absolute;
z-index: 9999; /* 仍然无法超越 .parent 的兄弟元素(z-index: 2) */
}
# 四、浮动 (Float)
虽然现代布局更推荐使用Flexbox和Grid,但了解浮动仍然很重要。
# 4.1 基本用法
.float-left {
float: left;
}
.float-right {
float: right;
}
.float-none {
float: none; /* 默认值 */
}
特点:
- 元素脱离文档流(部分)
- 其他元素会环绕浮动元素
- 常用于文字环绕图片、多列布局
<div class="container">
<img src="image.jpg" class="float-left">
<p>文字内容会环绕图片...</p>
</div>
.float-left {
float: left;
margin-right: 15px;
margin-bottom: 10px;
}
# 4.2 清除浮动
问题:浮动元素会导致父元素高度塌陷。
<div class="parent">
<div class="float-child">浮动元素</div>
</div>
<!-- parent高度为0 -->
解决方案:
# 方法1:clear 属性
.clear {
clear: both; /* left | right | both */
}
<div class="parent">
<div class="float-child">浮动元素</div>
<div class="clear"></div>
</div>
# 方法2:clearfix (推荐)
.clearfix::after {
content: "";
display: table;
clear: both;
}
<div class="parent clearfix">
<div class="float-child">浮动元素</div>
</div>
# 方法3:overflow
.parent {
overflow: hidden; /* 或 auto */
}
# 方法4:使用现代布局
/* 更推荐使用 Flexbox 或 Grid */
.parent {
display: flex;
}
# 五、overflow (溢出处理)
.box {
width: 200px;
height: 100px;
overflow: visible; /* 默认值,内容会溢出 */
overflow: hidden; /* 隐藏溢出内容 */
overflow: scroll; /* 始终显示滚动条 */
overflow: auto; /* 需要时显示滚动条 */
}
/* 单独控制 */
.box {
overflow-x: auto;
overflow-y: hidden;
}
应用场景:
/* 1. 文本截断 */
.ellipsis {
width: 200px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
/* 2. 滚动容器 */
.scroll-container {
height: 300px;
overflow-y: auto;
}
/* 3. 清除浮动 */
.clearfix {
overflow: hidden;
}
/* 4. 创建BFC */
.bfc {
overflow: hidden;
}
# 六、实战案例
# 6.1 卡片布局
# 6.2 水平垂直居中
# 6.3 图文混排
# 七、最佳实践
# 7.1 盒模型
/* 全局设置 border-box */
*, *::before, *::after {
box-sizing: border-box;
}
/* 避免固定高度,让内容撑开 */
.container {
/* height: 500px; ❌ 不推荐 */
min-height: 300px; /* ✅ 推荐 */
}
# 7.2 布局
/* 优先使用 Flexbox 或 Grid */
.layout {
display: flex; /* ✅ 推荐 */
/* float: left; ❌ 过时 */
}
/* 语义化定位 */
.modal {
position: fixed; /* 明确语义:固定在视口 */
}
.tooltip {
position: absolute; /* 明确语义:相对于父元素 */
}
# 7.3 性能优化
/* 避免过度使用定位 */
.item {
/* position: absolute; ❌ 会触发重排 */
transform: translateX(10px); /* ✅ 只触发重绘 */
}
/* 减少层叠上下文 */
.element {
/* z-index: 1; ❌ 非必要不设置 */
}
# 7.4 响应式设计
/* 使用相对单位 */
.container {
width: 100%;
max-width: 1200px;
padding: 0 20px;
margin: 0 auto;
}
/* 灵活的盒模型 */
.box {
width: 100%;
padding: 5%; /* 响应式内边距 */
}
@media (max-width: 768px) {
.box {
padding: 15px; /* 小屏固定值 */
}
}
# 八、浏览器兼容性
| 特性 | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| box-sizing | ✅ | ✅ | ✅ | ✅ |
| position: sticky | ✅ 56+ | ✅ 59+ | ✅ 13+ | ✅ 16+ |
| display: flex | ✅ | ✅ | ✅ | ✅ |
| display: grid | ✅ | ✅ | ✅ | ✅ |
注意事项:
position: sticky在IE中不支持- 旧版Safari需要
-webkit-box-sizing前缀 - 使用 Autoprefixer 自动添加浏览器前缀
# 九、总结
盒模型和布局是CSS的核心概念:
- 盒模型:理解
content-box和border-box的区别,推荐全局使用border-box - 外边距合并:掌握合并规则和避免方法
- display:灵活运用
block、inline、inline-block - position:理解5种定位方式的特点和应用场景
- 浮动:了解浮动原理和清除浮动方法
- 现代布局:优先使用 Flexbox 和 Grid(后续文章详述)
祝你变得更强!
编辑 (opens new window)
上次更新: 2025/11/20