Day-14-盒模型与布局

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: 完整的页面布局

要求

  1. 固定头部(高度 60px)
  2. 三栏内容区(左侧 200px,右侧 150px,中间自适应)
  3. 固定底部(高度 40px)
  4. 使用 Flexbox 实现

提示

body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

练习 2: 响应式图片网格

要求

  1. 大屏幕:4 列
  2. 中等屏幕:3 列
  3. 小屏幕:2 列
  4. 超小屏幕:1 列
  5. 图片等高、等宽

提示:使用 @media 查询

练习 3: 居中各种元素

要求

  1. 块级元素水平居中
  2. 行内元素水平居中
  3. 元素垂直居中
  4. 元素完全居中(水平+垂直)

提示

  • 水平居中:margin: 0 autojustify-content: center
  • 垂直居中:align-items: center + min-height

🎓 今日挑战

实现:响应式个人作品集页面

布局要求

  1. 响应式导航栏

    • 移动端:汉堡菜单
    • 桌面端:水平菜单
    • 使用 Flexbox
  2. Hero 区域

    • 全屏背景
    • 内容居中
    • CTA 按钮组
  3. 技能展示

    • 技能标签云
    • 进度条
    • 使用 Grid 布局
  4. 作品展示

    • 卡片网格
    • 悬停效果
    • 响应式(4→3→2→1 列)
  5. 联系表单

    • 两列布局(信息 + 表单)
    • 移动端单列

技术要点

  • 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;  /* 等高 */
}

📚 拓展阅读

相关主题

  1. CSS 定位:static、relative、absolute、fixed、sticky
  2. CSS 变换:transform、transition、animation
  3. 响应式设计:媒体查询、移动优先
  4. 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-样式