Day 14: 盒模型与布局
🎯 学习目标
- 深入理解 CSS 盒模型
- 掌握 display 属性和常见布局方案
- 学会使用 Flexbox 进行一维布局
- 了解 Grid 布局的基本概念
- 实现常见的页面布局模式
💡 核心概念
CSS 盒模型回顾
每个 HTML 元素都被表示为一个矩形的盒子,包含四个部分:
┌────────────────────────────────────────┐
│ Margin (外边距) │ ← 元素外部空间
├────────────────────────────────────────┤
│ Border (边框) │
├────────────────────────────────────────┤
│ Padding (内边距) │
│ ┌────────────────────────────┐ │
│ │ Content (内容区域) │ │ ← 实际内容
│ │ │ │
│ │ width × height │ │
│ └────────────────────────────┘ │
└────────────────────────────────────────┘
box-sizing 属性详解
/* content-box(默认 W3C 标准盒模型) */
.element {
box-sizing: content-box;
width: 200px;
padding: 20px; /* 总宽度 = 200 + 20×2 = 240px */
border: 5px solid; /* 总宽度 = 240 + 5×2 = 250px */
}
/* border-box(IE 盒模型,推荐使用)*/
.element {
box-sizing: border-box;
width: 200px;
padding: 20px; /* 内容宽度 = 200 - 20×2 - 5×2 = 150px */
border: 5px solid; /* 总宽度保持 200px */
}
最佳实践:
/* 全局设置为 border-box */
* {
box-sizing: border-box;
}
/* 或针对特定元素 */
.container {
box-sizing: border-box;
}
📝 Display 属性
display 值详解
/* 1. 块级元素 */
display: block;
/* 特点:
- 独占一行
- 可设置 width、height
- margin、padding 上下左右都有效
- 示例:div、p、h1-h6、ul、li
*/
/* 2. 行内元素 */
display: inline;
/* 特点:
- 不独占一行
- 不能设置 width、height
- 只有左右 margin、padding 有效
- 示例:span、a、strong、em
*/
/* 3. 行内块元素 */
display: inline-block;
/* 特点:
- 不独占一行
- 可以设置 width、height
- 所有方向 margin、padding 都有效
- 示例:img、input、button(默认)
*/
/* 4. 隐藏元素 */
display: none;
/* 元素完全从文档流中移除,不占用空间 */
/* 5. Flexbox 布局 */
display: flex;
/* 6. Grid 布局 */
display: grid;
示例:display 对比
<!DOCTYPE html>
<html>
<head>
<style>
.block {
display: block;
background-color: #f44336;
padding: 10px;
margin: 10px 0;
}
.inline {
display: inline;
background-color: #4CAF50;
padding: 10px;
margin: 10px;
}
.inline-block {
display: inline-block;
background-color: #2196F3;
padding: 10px;
margin: 10px;
width: 100px;
height: 50px;
}
</style>
</head>
<body>
<div class="block">块级元素 1</div>
<div class="block">块级元素 2</div>
<hr>
<span class="inline">行内元素 1</span>
<span class="inline">行内元素 2</span>
<span class="inline">行内元素 3</span>
<hr>
<div class="inline-block">行内块 1</div>
<div class="inline-block">行内块 2</div>
<div class="inline-block">行内块 3</div>
</body>
</html>
🎨 Flexbox 布局(弹性盒子)
什么是 Flexbox?
Flexbox(Flexible Box) 是一种一维布局模型,主要用于在容器中分配空间和对齐项目。
核心概念:
- Flex 容器(Flex Container):父元素
- Flex 项目(Flex Items):子元素
Flex 容器属性
1. flex-direction(主轴方向)
.container {
display: flex;
flex-direction: row; /* 默认,水平方向 */
/* flex-direction: row-reverse; 水平反向 */
/* flex-direction: column; 垂直方向 */
/* flex-direction: column-reverse; 垂直反向 */
}
示意图:
row: → → → → →
row-reverse: ← ← ← ← ←
column: ↓ ↓ ↓ ↓ ↓
column-reverse:↑ ↑ ↑ ↑ ↑
2. flex-wrap(换行)
.container {
flex-wrap: nowrap; /* 默认,不换行 */
/* flex-wrap: wrap; 换行,第一行在上方 */
/* flex-wrap: wrap-reverse; 换行,第一行在下方 */
}
3. flex-flow(简写)
.container {
flex-flow: row wrap; /* = flex-direction + flex-wrap */
}
4. justify-content(主轴对齐)
.container {
justify-content: flex-start; /* 默认,起点对齐 */
/* justify-content: flex-end; 终点对齐 */
/* justify-content: center; 居中对齐 */
/* justify-content: space-between; 两端对齐,项目间隔相等 */
/* justify-content: space-around; 每个项目两侧间隔相等 */
/* justify-content: space-evenly; 所有间隔相等 */
}
示意图(主轴为水平):
flex-start: [▣] [▣] [▣]
center: [▣] [▣] [▣]
space-between: [▣] --- [▣] --- [▣]
space-around: - [▣] - [▣] - [▣] -
5. align-items(交叉轴对齐)
.container {
align-items: stretch; /* 默认,拉伸填满 */
/* align-items: flex-start; 起点对齐 */
/* align-items: flex-end; 终点对齐 */
/* align-items: center; 居中对齐 */
/* align-items: baseline; 基线对齐 */
}
6. align-content(多行对齐)
.container {
align-content: stretch; /* 默认 */
/* align-content: flex-start; */
/* align-content: flex-end; */
/* align-content: center; */
/* align-content: space-between; */
/* align-content: space-around; */
}
Flex 项目属性
1. flex-grow(放大比例)
.item {
flex-grow: 0; /* 默认,不放大 */
/* flex-grow: 1; 所有项目平分剩余空间 */
/* flex-grow: 2; 占用 2 份剩余空间 */
}
2. flex-shrink(缩小比例)
.item {
flex-shrink: 1; /* 默认,可以缩小 */
/* flex-shrink: 0; 不缩小 */
}
3. flex-basis(基础大小)
.item {
flex-basis: auto; /* 默认 */
/* flex-basis: 200px; 固定基础大小 */
/* flex-basis: 30%; 百分比 */
}
4. flex(简写)
.item {
flex: 0 1 auto; /* 默认 */
/* flex: 1; = flex: 1 1 0% */
/* flex: 2; = flex: 2 1 0% */
/* flex: auto; = flex: 1 1 auto */
/* flex: none; = flex: 0 0 auto */
}
常用值:
/* 平分空间 */
.item {
flex: 1;
}
/* 固定宽度,不放大不缩小 */
.item {
flex: 0 0 200px;
}
/* 放大但不缩小 */
.item {
flex: 1 0 auto;
}
5. align-self(单独对齐)
.item {
align-self: auto; /* 默认,继承容器的 align-items */
/* align-self: flex-start; */
/* align-self: flex-end; */
/* align-self: center; */
}
🎮 Flexbox 示例
示例 1: 水平居中
<style>
.container {
display: flex;
justify-content: center;
align-items: center;
height: 200px;
background-color: #f0f0f0;
}
.box {
width: 100px;
height: 100px;
background-color: #4CAF50;
}
</style>
<div class="container">
<div class="box">居中</div>
</div>
示例 2: 三栏布局
<style>
.container {
display: flex;
height: 300px;
}
.sidebar-left {
flex: 0 0 200px;
background-color: #f44336;
}
.main {
flex: 1;
background-color: #2196F3;
}
.sidebar-right {
flex: 0 0 150px;
background-color: #4CAF50;
}
</style>
<div class="container">
<div class="sidebar-left">左侧栏</div>
<div class="main">主内容</div>
<div class="sidebar-right">右侧栏</div>
</div>
示例 3: 导航栏
<style>
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #333;
padding: 0 20px;
height: 60px;
}
.logo {
color: white;
font-size: 24px;
font-weight: bold;
}
.nav-links {
display: flex;
gap: 20px;
}
.nav-links a {
color: white;
text-decoration: none;
}
</style>
<div class="navbar">
<div class="logo">Logo</div>
<div class="nav-links">
<a href="#">首页</a>
<a href="#">产品</a>
<a href="#">关于</a>
<a href="#">联系</a>
</div>
</div>
示例 4: 卡片网格
<style>
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 20px;
padding: 20px;
}
.card {
flex: 0 0 calc(33.333% - 20px);
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
padding: 20px;
}
@media (max-width: 768px) {
.card {
flex: 0 0 calc(50% - 20px);
}
}
@media (max-width: 480px) {
.card {
flex: 0 0 100%;
}
}
</style>
<div class="card-grid">
<div class="card">卡片 1</div>
<div class="card">卡片 2</div>
<div class="card">卡片 3</div>
<div class="card">卡片 4</div>
<div class="card">卡片 5</div>
<div class="card">卡片 6</div>
</div>
🎨 Grid 布局简介
什么是 Grid?
CSS Grid 是一种二维布局系统,可以同时处理行和列。
基本语法
.container {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* 三列,比例 1:2:1 */
grid-template-rows: 100px 200px; /* 两行,固定高度 */
gap: 20px; /* 间距 */
}
.item {
grid-column: 1 / 3; /* 跨越两列 */
grid-row: 1 / 2; /* 第一行 */
}
Grid 示例
<style>
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
padding: 20px;
}
.grid-item {
background-color: #4CAF50;
padding: 20px;
text-align: center;
color: white;
}
</style>
<div class="grid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
</div>
⚠️ 重要注意事项
1. box-sizing 的重要性
/* 全局设置,避免布局意外 */
* {
box-sizing: border-box;
}
2. 响应式设计
/* 移动优先 */
.container {
display: flex;
flex-direction: column; /* 移动端垂直 */
}
@media (min-width: 768px) {
.container {
flex-direction: row; /* 桌面端水平 */
}
}
3. 浏览器兼容性
/* Flexbox 需要厂商前缀(旧浏览器)*/
.container {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
现代浏览器支持:
- Flexbox:IE 11+(部分支持)
- Grid:IE 11-(不支持,需前缀)
✍️ 练习任务
练习 1: 完整的页面布局
要求:
- 固定头部(高度 60px)
- 三栏内容区(左侧 200px,右侧 150px,中间自适应)
- 固定底部(高度 40px)
- 使用 Flexbox 实现
提示:
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
练习 2: 响应式图片网格
要求:
- 大屏幕:4 列
- 中等屏幕:3 列
- 小屏幕:2 列
- 超小屏幕:1 列
- 图片等高、等宽
提示:使用 @media 查询
练习 3: 居中各种元素
要求:
- 块级元素水平居中
- 行内元素水平居中
- 元素垂直居中
- 元素完全居中(水平+垂直)
提示:
- 水平居中:
margin: 0 auto或justify-content: center - 垂直居中:
align-items: center+min-height
🎓 今日挑战
实现:响应式个人作品集页面
布局要求:
-
响应式导航栏
- 移动端:汉堡菜单
- 桌面端:水平菜单
- 使用 Flexbox
-
Hero 区域
- 全屏背景
- 内容居中
- CTA 按钮组
-
技能展示
- 技能标签云
- 进度条
- 使用 Grid 布局
-
作品展示
- 卡片网格
- 悬停效果
- 响应式(4→3→2→1 列)
-
联系表单
- 两列布局(信息 + 表单)
- 移动端单列
技术要点:
- Flexbox + Grid 混合使用
- 响应式断点:768px、480px
- 平滑过渡效果
💡 常见问题 FAQ
Q1: Flexbox 和 Grid 如何选择?
A:
| 场景 | Flexbox | Grid |
|---|---|---|
| 一维布局 | ✅ 推荐 | ❌ 过度 |
| 二维布局 | ❌ 复杂 | ✅ 推荐 |
| 内容驱动 | ✅ 灵活 | ⚠️ 需计算 |
| 布局驱动 | ⚠️ 复杂 | ✅ 简单 |
| 浏览器支持 | ✅ 更好 | ⚠️ 较新 |
建议:
- 简单布局 → Flexbox
- 复杂二维布局 → Grid
- 两者可以混合使用
Q2: 如何实现完美的垂直居中?
A:
/* 方法1:Flexbox(推荐)*/
.parent {
display: flex;
justify-content: center;
align-items: center;
}
/* 方法2:Grid */
.parent {
display: grid;
place-items: center;
}
/* 方法3:绝对定位 + transform */
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
Q3: flex: 1 和 flex: auto 有什么区别?
A:
/* flex: 1 = flex: 1 1 0% */
.item {
flex: 1;
/* 忽略内容大小,完全平分空间 */
}
/* flex: auto = flex: 1 1 auto */
.item {
flex: auto;
/* 考虑内容大小,然后平分剩余空间 */
}
示例:
<div style="display: flex; width: 600px;">
<div style="flex: 1; background: red;">
短内容
</div>
<div style="flex: 1; background: blue;">
这是非常非常非常长的内容
</div>
</div>
<!-- 两者等宽 -->
<div style="display: flex; width: 600px;">
<div style="flex: auto; background: red;">
短内容
</div>
<div style="flex: auto; background: blue;">
这是非常非常非常长的内容
</div>
</div>
<!-- 蓝色更宽,因为内容更长 -->
Q4: gap 属性的兼容性?
A:
/* 现代浏览器 */
.container {
display: flex;
gap: 20px;
}
/* 旧浏览器回退方案 */
.container {
display: flex;
margin: -10px;
}
.item {
margin: 10px;
}
/* 或使用负 margin */
.container {
display: flex;
}
.item {
margin-right: 20px;
}
.item:last-child {
margin-right: 0;
}
Q5: 如何实现等高列?
A:
/* Flexbox 自动等高 */
.container {
display: flex;
align-items: stretch; /* 默认值 */
}
.column {
flex: 1;
}
Grid 也自动等高:
.container {
display: grid;
grid-auto-rows: 1fr; /* 等高 */
}
📚 拓展阅读
相关主题
- CSS 定位:static、relative、absolute、fixed、sticky
- CSS 变换:transform、transition、animation
- 响应式设计:媒体查询、移动优先
- CSS 预处理器:Sass、Less
推荐资源
- Flexbox Froggy: 互动游戏学习 Flexbox
- CSS Grid Garden: 互动游戏学习 Grid
- Can I Use: 查询浏览器兼容性
- MDN Web Docs: 权威的 CSS 文档
学习时间: 2026-03-13 09:14
难度: ⭐⭐⭐⭐☆
预计用时: 4-5 小时
关键词: 盒模型, Flexbox, Grid, 布局, display
相关标签: #08-样式