【HTML+CSS】day08-flex-advanced

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

第八天:Flex 进阶 — 让每个项目有自己的"个性"

蜗牛往上爬 · 前端工业可视化学习笔记 第 8 篇
上一篇学会了用容器属性让所有项目"整齐排队"。今天学项目属性——让每个项目有自己的"个性":有的撑满剩余空间、有的固定宽度、有的单独控制对齐。这是 Flex 从"能用"到"好用"的关键一步。


目录


一、项目属性速查

容器属性控制"整体",项目属性控制"个别":

.item {
  /* ① 放大比例:剩余空间怎么分 */
  flex-grow: 0;       /* 默认 0(不放大),设为 1 会均分剩余空间 */

  /* ② 缩小比例:空间不足时谁先缩小 */
  flex-shrink: 1;     /* 默认 1(允许缩小),0 表示不缩小 */

  /* ③ 基础大小:分配剩余空间前的初始尺寸 */
  flex-basis: auto;   /* 默认 auto(由内容决定),可设具体值如 200px */

  /* ④ 简写(推荐!) */
  flex: 0 1 auto;     /* grow shrink basis */

  /* ⑤ 单独控制自己的交叉轴对齐 */
  align-self: auto;   /* 覆盖容器的 align-items,只影响自己 */

  /* ⑥ 排列顺序:数值越小越靠前 */
  order: 0;           /* 默认 0,可设负数 */
}

二、flex-grow:瓜分剩余空间

flex-grow 是 Flex 最常用的项目属性,它决定了"剩余空间怎么分"。

图解

容器宽 600px,三个项目内容各 100px,剩余空间 300px

不放大(flex-grow: 0):
[100px] [100px] [100px] ············300px 空白············

全部放大(flex-grow: 1):
[  200px  ] [  200px  ] [  200px  ]  剩余空间均分

第一项放大(flex-grow: 1),其余不放大:
[    400px    ] [100px] [100px]  第一项独占剩余空间

按比例放大(flex-grow: 2, 1, 1):
[  250px  ] [ 175px ] [ 175px ]  2:1:1 分配

代码示例

/* 三列等宽(最常用) */
.col { flex: 1; }

/* 第一列占 2 份,其余各占 1 份 */
.col-1 { flex: 2; }
.col-2 { flex: 1; }
.col-3 { flex: 1; }

三、flex 简写:四个常用组合

flexflex-growflex-shrinkflex-basis 的简写,记住这四个组合就够用了:

flex: 1;           /* = flex: 1 1 0%    均分剩余空间,最常用 */
flex: auto;        /* = flex: 1 1 auto  根据内容比例均分 */
flex: none;        /* = flex: 0 0 auto  不伸缩,保持内容大小 */
flex: initial;     /* = flex: 0 1 auto  默认值 */

场景对照

需求

写法

解释

均分宽度

flex: 1

不管内容多少,都均分

侧边栏固定

flex: 0 0 240px

不放大、不缩小、固定 240px

主内容撑满

flex: 1

占满剩余空间

卡片固定宽度

flex: 0 0 280px

每张卡片 280px,不伸缩

经典组合:侧边栏 + 主内容

.container { display: flex; }

/* 侧边栏固定 240px,不伸缩 */
.sidebar { flex: 0 0 240px; }

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

四、align-self 与 order

4.1 align-self:单独控制某个项目

/* 所有项目顶对齐,但第三个项目底对齐 */
.container { align-items: flex-start; }
.item-3   { align-self: flex-end; }

场景:导航栏中,Logo 垂直居中,但右侧的用户头像想顶部对齐。

4.2 order:调整排列顺序

/* 默认所有项目 order: 0,按 HTML 顺序排列 */
/* 第二个项目排到第一个 */
.item-2 { order: -1; }

/* 第一个项目排到最后 */
.item-1 { order: 1; }

场景:移动端侧边栏在下,桌面端侧边栏在左——用 order 调整,不改变 HTML。


五、动手练:顶部导航 + 内容区页面

用 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;
      }

      /* 顶部导航栏 */
      .navbar {
        display: flex;
        justify-content: space-between;
        align-items: center;
        background: #1a3a5c;
        color: white;
        padding: 0 40px;
        height: 60px;
        flex-shrink: 0;          /* 不缩小 */
      }

      .navbar .logo {
        font-size: 20px;
        font-weight: bold;
      }

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

      .nav-menu a {
        color: #8ecae6;
        text-decoration: none;
      }

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

      /* 内容区 */
      .content {
        display: flex;
        flex: 1;                 /* 撑满导航下方空间 */
      }

      /* 侧边栏:固定宽度 */
      .sidebar {
        flex: 0 0 220px;         /* 不放大、不缩小、固定 220px */
        background: #e9ecef;
        padding: 20px;
      }

      .sidebar h3 {
        color: #1a3a5c;
        margin-bottom: 16px;
        font-size: 16px;
      }

      .sidebar ul {
        list-style: none;
      }

      .sidebar li {
        padding: 8px 0;
        color: #555;
        cursor: pointer;
      }

      .sidebar li:hover {
        color: #1a3a5c;
      }

      /* 主内容区:撑满剩余空间 */
      .main-content {
        flex: 1;                 /* 占据剩余空间 */
        padding: 20px;
      }

      .main-content h2 {
        color: #1a3a5c;
        margin-bottom: 16px;
      }

      /* 卡片网格 */
      .card-grid {
        display: flex;
        flex-wrap: wrap;         /* 自动换行 */
        gap: 16px;
      }

      .card {
        width: 280px;
        background: white;
        padding: 20px;
        border-radius: 8px;
        border: 1px solid #dee2e6;
      }

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

      .card p {
        color: #555;
        font-size: 14px;
        line-height: 1.6;
      }
    </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>
      </ul>
    </nav>

    <div class="content">
      <aside class="sidebar">
        <h3>设备分类</h3>
        <ul>
          <li>压缩机</li>
          <li>冷却泵</li>
          <li>供料机</li>
          <li>传送带</li>
          <li>包装机</li>
        </ul>
      </aside>

      <main class="main-content">
        <h2>设备概览</h2>
        <div class="card-grid">
          <div class="card">
            <h4>压缩机 A</h4>
            <p>温度:58℃ | 状态:运行中</p>
          </div>
          <div class="card">
            <h4>冷却泵 B</h4>
            <p>温度:32℃ | 状态:待机</p>
          </div>
          <div class="card">
            <h4>供料机 C</h4>
            <p>温度:45℃ | 状态:运行中</p>
          </div>
          <div class="card">
            <h4>传送带 D</h4>
            <p>速度:2.1m/s | 状态:运行中</p>
          </div>
        </div>
      </main>
    </div>
  </body>
</html>

Flex 属性分析

元素

Flex 属性

效果

body

flex-direction: column

垂直排列

.navbar

flex-shrink: 0

高度固定,不缩小

.content

flex: 1

撑满剩余空间

.sidebar

flex: 0 0 220px

固定 220px

.main-content

flex: 1

撑满剩余空间

.card-grid

flex-wrap: wrap; gap: 16px

自动换行

练习:照敲 → 把侧边栏的 flex: 0 0 220px 改成 flex: 0 0 300px → 把卡片改成 flex: 1 均分 → 缩窄浏览器窗口观察换行。


六、常见坑点与最佳实践

坑 1:flex: 1 和 flex: auto 的区别

/* flex: 1 = flex: 1 1 0% —— 忽略内容,纯均分 */
.item-1 { flex: 1; }

/* flex: auto = flex: 1 1 auto —— 考虑内容宽度后均分 */
.item-2 { flex: auto; }

当内容宽度差异大时,flex: 1 严格均分,flex: auto 按内容比例分。

坑 2:设了 flex-grow 但没撑满

/* 原因:容器没有剩余空间 */
/* 检查:容器是否设了固定宽度?内容是否已经撑满? */

最佳实践清单

  • [x] 均分用 flex: 1,固定用 flex: 0 0 XXXpx

  • [x] 记住 flex: 1grow: 1, shrink: 1, basis: 0%

  • [x] align-self 只影响自己,order 不改变 HTML


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

大屏布局:导航 + 侧边栏 + 主内容

/* 大屏的标准布局就是 Flex 的经典组合 */
body { display: flex; flex-direction: column; height: 100vh; }

.header  { flex-shrink: 0; height: 60px; }
.content { flex: 1; display: flex; }
.sidebar { flex: 0 0 200px; }
.main    { flex: 1; display: flex; flex-wrap: wrap; gap: 12px; }

响应式面板:不同宽度用不同 flex

/* 大屏:4 列,均分 */
.panel { flex: 1; }

/* 中屏:2 列,每列 380px */
.panel { flex: 0 0 380px; }

八、自测挑战 10 题

  1. flex-growflex-shrinkflex-basis 分别控制什么?

  2. flex: 1 等价于什么?flex: none 等价于什么?

  3. 侧边栏固定 200px,主内容区撑满剩余空间,怎么写?

  4. align-selfalign-items 有什么区别?

  5. order 改变的是什么?会改变 HTML 结构吗?

  6. 写出 body 用 Flex 实现"导航在上、内容在下"的代码。

  7. 写出"侧边栏 + 主内容区"的 Flex 代码(含 flex 值)。

  8. flex-wrap: wrap 配合 gap 能实现什么布局效果?

  9. 把卡片网格的 flex-wrap 去掉,缩窄窗口,观察卡片是否被压缩。

  10. 用 F12 把 .sidebarflex 值从 0 0 220px 改成 1,观察宽度变化。

加分挑战:在页面中给侧边栏的某个菜单项设 align-self: flex-end,让它沉到底部。


九、总结

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

  • [x] 解释 flex-growflex-shrinkflex-basis 的作用

  • [x] 使用 flex: 1flex: noneflex: 0 0 XXXpx 等常用组合

  • [x] 实现"侧边栏固定 + 主内容撑满"的经典布局

  • [x] 使用 align-selforder 单独控制项目

  • [x] 独立做出"顶部导航 + 内容区"页面

一句话带走flex: 1 均分,flex: 0 0 240px 固定,flex-shrink: 0 不缩小——记住这三个组合,覆盖 90% 的 Flex 布局场景。


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

评论