【HTML+CSS】day09-flex-comprehensive

作者:mario 发布时间: 2026-08-18 阅读量:2 评论数:0

第九天:Flex 综合布局 — 搭一个完整的企业信息展示页

蜗牛往上爬 · 前端工业可视化学习笔记 第 9 篇
前两天分别学了 Flex 的容器属性和项目属性,今天把它们全部用上,搭一个完整的企业信息展示页——顶部导航 + 侧边栏 + 统计卡片 + 设备列表 + 页脚。这个页面就是未来大屏页面的雏形。


目录


一、三种经典页面骨架

骨架 1:顶部导航 + 下方内容

body {
  display: flex;
  flex-direction: column;  /* 垂直排列 */
  min-height: 100vh;       /* 至少占满整个视口 */
}

.navbar {
  flex-shrink: 0;          /* 导航栏高度固定,不缩小 */
  height: 60px;
}

.content {
  flex: 1;                 /* 撑满导航下方剩余空间 */
}

骨架 2:侧边栏 + 主内容

.container {
  display: flex;
}

.sidebar {
  flex: 0 0 240px;         /* 固定宽度 240px */
}

.main {
  flex: 1;                 /* 撑满剩余空间 */
}

骨架 3:卡片列表(自动换行)

.card-grid {
  display: flex;
  flex-wrap: wrap;         /* 放不下就换行 */
  gap: 16px;               /* 统一间距 */
}

.card {
  flex: 0 0 280px;         /* 每张卡片 280px,不伸缩 */
}

二、Flex 布局模式速查表

需求

核心代码

水平居中

display: flex; justify-content: center;

垂直居中

display: flex; align-items: center;

水平垂直居中

display: flex; justify-content: center; align-items: center;

两端对齐

display: flex; justify-content: space-between;

等距排列

display: flex; gap: 16px;

固定侧边栏

sidebar { flex: 0 0 240px; }

均分剩余空间

item { flex: 1; }

自动换行

display: flex; flex-wrap: wrap; gap: 16px;

垂直排列

flex-direction: column;

某个项目特殊对齐

align-self: flex-end;


三、动手练:企业信息展示页

综合 Flex 全部知识,做一个完整的企业信息展示页。

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8">
    <title>企业信息展示页</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      body {
        font-family: "Microsoft YaHei", sans-serif;
        display: flex;
        flex-direction: column;
        min-height: 100vh;
        background: #f0f2f5;
      }

      /* ===== 顶部导航栏 ===== */
      .navbar {
        display: flex;
        justify-content: space-between;
        align-items: center;
        background: linear-gradient(135deg, #1a3a5c, #2d5a8c);
        color: white;
        padding: 0 40px;
        height: 64px;
        flex-shrink: 0;
      }

      .navbar .logo {
        font-size: 22px;
        font-weight: bold;
        letter-spacing: 2px;
      }

      .nav-menu {
        display: flex;
        list-style: none;
        gap: 28px;
      }

      .nav-menu a {
        color: #8ecae6;
        text-decoration: none;
        font-size: 15px;
        transition: color 0.2s;
      }

      .nav-menu a:hover {
        color: #ffb703;
      }

      /* ===== 内容区 ===== */
      .content {
        display: flex;
        flex: 1;
      }

      /* 侧边栏 */
      .sidebar {
        flex: 0 0 240px;
        background: white;
        padding: 20px;
        border-right: 1px solid #e0e0e0;
      }

      .sidebar h3 {
        font-size: 14px;
        color: #888;
        text-transform: uppercase;
        margin-bottom: 12px;
        letter-spacing: 1px;
      }

      .sidebar-menu {
        list-style: none;
      }

      .sidebar-menu li {
        padding: 10px 12px;
        border-radius: 6px;
        color: #555;
        font-size: 15px;
        cursor: pointer;
        margin-bottom: 4px;
        transition: all 0.2s;
      }

      .sidebar-menu li:hover,
      .sidebar-menu li.active {
        background: #e8f0fe;
        color: #1a3a5c;
        font-weight: bold;
      }

      /* 主内容区 */
      .main-content {
        flex: 1;
        padding: 24px;
        display: flex;
        flex-direction: column;
        gap: 24px;
      }

      .main-content h2 {
        color: #1a3a5c;
        font-size: 20px;
      }

      /* 统计卡片行 */
      .stats-row {
        display: flex;
        gap: 16px;
      }

      .stat-card {
        flex: 1;
        background: white;
        padding: 20px;
        border-radius: 8px;
        border: 1px solid #e0e0e0;
        text-align: center;
      }

      .stat-card .number {
        font-size: 32px;
        font-weight: bold;
        color: #1a3a5c;
      }

      .stat-card .label {
        font-size: 14px;
        color: #888;
        margin-top: 4px;
      }

      .stat-card.warning .number {
        color: #d62828;
      }

      .stat-card.success .number {
        color: #2d6a4f;
      }

      /* 设备列表 */
      .device-list {
        display: flex;
        flex-wrap: wrap;
        gap: 16px;
      }

      .device-card {
        flex: 0 0 280px;
        background: white;
        padding: 20px;
        border-radius: 8px;
        border: 1px solid #e0e0e0;
        border-left: 4px solid #1a3a5c;
      }

      .device-card h4 {
        color: #1a3a5c;
        margin-bottom: 8px;
      }

      .device-card .info {
        color: #555;
        line-height: 1.8;
        font-size: 14px;
      }

      .device-card .status {
        display: inline-block;
        padding: 2px 10px;
        border-radius: 12px;
        font-size: 12px;
        font-weight: bold;
      }

      .status-running {
        background: #d4edda;
        color: #2d6a4f;
      }

      .status-stopped {
        background: #f8d7da;
        color: #d62828;
      }

      /* 页脚 */
      .footer {
        background: #1a3a5c;
        color: #8ecae6;
        text-align: center;
        padding: 16px;
        font-size: 14px;
        flex-shrink: 0;
      }
    </style>
  </head>
  <body>
    <!-- 顶部导航 -->
    <nav class="navbar">
      <div class="logo">智慧工厂 · 监控中心</div>
      <ul class="nav-menu">
        <li><a href="#">设备监控</a></li>
        <li><a href="#">产量统计</a></li>
        <li><a href="#">告警中心</a></li>
        <li><a href="#">报表管理</a></li>
        <li><a href="#">系统设置</a></li>
      </ul>
    </nav>

    <!-- 内容区 -->
    <div class="content">
      <aside class="sidebar">
        <h3>导航菜单</h3>
        <ul class="sidebar-menu">
          <li class="active">设备概览</li>
          <li>实时监控</li>
          <li>历史数据</li>
          <li>告警记录</li>
          <li>维护计划</li>
        </ul>
      </aside>

      <main class="main-content">
        <h2>设备概览</h2>

        <!-- 统计卡片行 -->
        <div class="stats-row">
          <div class="stat-card">
            <div class="number">48</div>
            <div class="label">设备总数</div>
          </div>
          <div class="stat-card success">
            <div class="number">42</div>
            <div class="label">运行中</div>
          </div>
          <div class="stat-card warning">
            <div class="number">3</div>
            <div class="label">告警中</div>
          </div>
          <div class="stat-card">
            <div class="number">3</div>
            <div class="label">已停机</div>
          </div>
        </div>

        <!-- 设备列表 -->
        <div class="device-list">
          <div class="device-card">
            <h4>压缩机 A</h4>
            <p class="info">
              车间:一车间<br>
              温度:58℃<br>
              时长:72 小时<br>
              <span class="status status-running">运行中</span>
            </p>
          </div>
          <div class="device-card">
            <h4>冷却泵 B</h4>
            <p class="info">
              车间:二车间<br>
              温度:32℃<br>
              时长:120 小时<br>
              <span class="status status-stopped">已停机</span>
            </p>
          </div>
          <div class="device-card">
            <h4>供料机 C</h4>
            <p class="info">
              车间:一车间<br>
              温度:45℃<br>
              时长:56 小时<br>
              <span class="status status-running">运行中</span>
            </p>
          </div>
          <div class="device-card">
            <h4>传送带 D</h4>
            <p class="info">
              车间:三车间<br>
              速度:2.1m/s<br>
              时长:200 小时<br>
              <span class="status status-running">运行中</span>
            </p>
          </div>
        </div>
      </main>
    </div>

    <!-- 页脚 -->
    <footer class="footer">
      © 2026 智慧工厂 · 蜗牛往上爬 学习项目
    </footer>
  </body>
</html>

四、Flex 属性全景分析

这个页面用了 10 个 Flex 容器,每个都值得分析:

#

元素

Flex 属性

效果

1

body

display: flex; flex-direction: column; min-height: 100vh

导航 + 内容 + 页脚垂直排列

2

.navbar

display: flex; justify-content: space-between; align-items: center

Logo 左、菜单右,垂直居中

3

.navbar

flex-shrink: 0

高度固定,不缩小

4

.nav-menu

display: flex; gap: 28px

菜单项水平排列

5

.content

display: flex; flex: 1

侧边栏 + 主内容水平排列,撑满剩余空间

6

.sidebar

flex: 0 0 240px

固定 240px,不伸缩

7

.main-content

flex: 1

撑满剩余空间

8

.stats-row

display: flex; gap: 16px

统计卡片一行排开

9

.stat-card

flex: 1

四张卡片均分宽度

10

.device-list

display: flex; flex-wrap: wrap; gap: 16px

设备卡片自动换行

🧠 这个页面就是未来大屏的雏形。把 body 换成 100vh、去掉页脚、把内容换成深色主题,就是一个大屏页面。


五、常见坑点与最佳实践

坑 1:嵌套 Flex 时忘记设 flex-direction

/* ❌ .main-content 的子元素需要垂直排列,但没设 flex-direction */
.main-content { display: flex; flex: 1; }
/* 子元素会水平排列,不是想要的效果 */

/* ✅ 加上 flex-direction: column */
.main-content { display: flex; flex: 1; flex-direction: column; }

坑 2:容器高度问题

/* ❌ 父元素没设高度,flex: 1 不生效 */
body { display: flex; flex-direction: column; }
/* 缺少 min-height: 100vh */

/* ✅ 加上 min-height */
body { display: flex; flex-direction: column; min-height: 100vh; }

最佳实践清单

  • [x] 用 flex-direction: column 做垂直布局

  • [x] 嵌套 Flex 时,每个容器独立设 flex-direction

  • [x] 卡片列表用 flex-wrap: wrap + gap + flex: 0 0 280px

  • [x] 统计卡片用 flex: 1 均分


六、这些知识在工业可视化里用在哪?

这个"企业信息展示页"只需要三步改造,就能变成大屏页面:

/* 改造 1:深色背景 + 全屏 */
body {
  background: linear-gradient(135deg, #0a1628, #1a3a5c);
  min-height: 100vh;
  overflow: hidden;
}

/* 改造 2:面板半透明 */
.stat-card, .device-card {
  background: rgba(10, 20, 40, 0.8);
  border-color: rgba(26, 92, 138, 0.4);
  color: #8ecae6;
}

/* 改造 3:数据高亮 */
.stat-card .number {
  color: #00ff88;
  font-size: 40px;
}

结构完全不变,只改 CSS 颜色和背景。 这就是 HTML/CSS 分离的好处——结构一次搭好,样式随时换。


七、自测挑战 10 题

  1. 用 Flex 实现"顶部导航 + 下方内容"布局,写出关键 CSS。

  2. 用 Flex 实现"侧边栏 + 主内容"布局,写出关键 CSS。

  3. 统计卡片行的四张卡片如何做到均分宽度?

  4. 设备卡片列表如何做到自动换行?

  5. flex: 1flex: 0 0 280px 分别适合什么场景?

  6. 把企业信息展示页的侧边栏从左侧移到右侧,只改 CSS(提示:order)。

  7. 把统计卡片行改成两行两列(提示:flex-wrap)。

  8. 在不改变 HTML 的情况下,用 order 把"告警中"卡片排到第一个。

  9. 给企业信息展示页加一个页面级水平垂直居中(.container 包住所有内容)。

  10. 用 F12 把 .device-cardflex0 0 280px 改成 1,观察卡片宽度变化。

加分挑战:把企业信息展示页的 CSS 颜色全部改成深色主题(黑底蓝字),不改变 HTML 结构。


八、总结

今天学完,你应该能做到:

  • [x] 用 Flex 实现三种经典页面骨架

  • [x] 记住 Flex 布局常用模式速查表

  • [x] 独立做出"企业信息展示页"(导航 + 侧边栏 + 统计卡片 + 设备列表 + 页脚)

  • [x] 理解 10 个 Flex 容器的分工协作

  • [x] 知道如何把普通页面改造成大屏页面

一句话带走:Flex 是 CSS 布局的"万能钥匙"——一个页面可以由多个 Flex 容器嵌套组成,每个容器负责自己那一层的排列。掌握它,你就掌握了前端布局的 80%。


📎 本文为"蜗牛往上爬"学习博客系列 · 阶段 0(HTML+CSS)第 3 周 · 第 3 篇

评论