首页
/ freeCodeCamp CSS Flexbox 教程实战:用 flex-direction: column 让弹性子项垂直堆叠

freeCodeCamp CSS Flexbox 教程实战:用 flex-direction: column 让弹性子项垂直堆叠

2026-09-07 19:11:46作者:明树来

本文基于 freeCodeCamp 开源课程库中 css-flexbox 块 的第 5 个挑战(源文件:587d78ac367417b2b2512af4.md),系统讲解如何在弹性容器(flex container)中使用 flex-direction: column 把子元素改为纵向堆叠,并顺带剖析 freeCodeCamp 挑战文件的组织方式与自动判题原理。读完你既能独立完成该关卡,也能理解 freeCodeCamp 用一条 CSS 规则配合最小化 DOM 进行教学的设计思路,并可直接把同一套纵向排列技巧应用到自己的布局中。

这节课在 freeCodeCamp 课程体系中的位置

自由代码营把每个知识点封装成一份带结构化 frontmatter 的 Markdown 挑战文件。本课对应的文件是 curriculum/challenges/english/blocks/css-flexbox/587d78ac367417b2b2512af4.md,文件名本身即挑战 ID 587d78ac367417b2b2512af4

在课程结构描述文件 curriculum/structure/blocks/css-flexbox.json 中,css-flexbox 块共编排了 17 个循序渐进的小挑战,覆盖 display: flexflex-directionjustify-contentalign-itemsflex-wrapflex-shrinkflex-growflex-basisflex 简写、orderalign-self 等核心知识点;本课(标题为 “Use the flex-direction Property to Make a Column”)是其中的第 5 个条目,紧跟在“Make a Row”与 Twitter 卡片行布局两个练习之后,属于 Responsive Web Design 超级块(该块在 responsive-web-design*.json 系列结构文件中被引用)下 HTML/CSS 方向的学习路径,块布局类型为 legacy-challenge-list

认识 flex-direction:弹性容器决定主轴方向

本课描述开头直接点明前两个挑战已经把 flex-direction 设置成了 row。在进一步动手前,先厘清这套 CSS 机制:

  • 给父元素加上 display: flex,它就变成一个弹性容器,其所有直接子元素自动成为弹性项目(flex items)。
  • flex-direction 作用在父容器上,用来决定弹性项目沿主轴(main axis)的排列方向,从而把子元素排成行或列。
  • 默认值是 row(子元素水平排成一行);设为 column 后主轴变为垂直方向,子元素由上到下纵向堆叠成列

参考同块前一个挑战 587d78ab367417b2b2512af2.md 的说明,flex-direction 一共有四个取值,可归纳如下:

取值 主轴方向 子元素视觉效果
row 水平(从左到右) 排成一行(默认值)
row-reverse 水平(从右到左) 排成一行,起点换到右侧
column 垂直(从上到下) 纵向堆叠成一列
column-reverse 垂直(从下到上) 纵向堆叠成一列,起点换到底部

需要特别留意:column 并不是“没有布局”,而是把布局方向从水平切换为垂直——主轴与侧轴(cross axis)互换,主轴上的尺寸控制、对齐属性(如后文课程会讲的 justify-content 控制主轴方向)随之作用于垂直方向。

挑战目标与初始代码

本课的指令非常聚焦:

#box-container 元素添加 CSS 属性 flex-direction,并把值设为 column

挑战的初始代码(seed)提供了一个最小的实验环境:

<style>
  #box-container {
    display: flex;
    height: 500px;

  }
  #box-1 {
    background-color: dodgerblue;
    width: 50%;
    height: 50%;
  }

  #box-2 {
    background-color: orangered;
    width: 50%;
    height: 50%;
  }
</style>

<div id="box-container">
  <div id="box-1"></div>
  <div id="box-2"></div>
</div>

先分析这份 seed 的意图:

  • #box-container 已经通过 display: flex 成为弹性容器,固定 height: 500px,但目前没有声明 flex-direction,因此采用默认值 row——此时 #box-1(道奇蓝)与 #box-2(橘红)会水平并排在同一行内,尽管每个盒子声明了 width: 50%height: 50%
  • 两个子盒子的尺寸都被设为容器的一半,且两色对比明显,能让学习者一眼看出布局方向的差异:row 时两个色块左右并排;改为 column 后主轴变成垂直方向,两个色块改为上下排列。

编写答案:一行 CSS 把排列改为纵向

按照指令,只需在 #box-container 的规则内补上一行,使其成为纵向布局:

<style>
  #box-container {
    display: flex;
    height: 500px;
    flex-direction: column;
  }
  #box-1 {
    background-color: dodgerblue;
    width: 50%;
    height: 50%;
  }

  #box-2 {
    background-color: orangered;
    width: 50%;
    height: 50%;
  }
</style>

要点与效果说明:

  1. flex-direction: column 声明在父容器上,子元素无需任何改动即会响应方向变化——这正是弹性布局“由容器统一指挥子项排列方向”的核心特征。
  2. 方向改为纵向后,主轴变为垂直:#box-1#box-2 各占容器一半高度(在 500px 容器下约为各 250px),由上而下依次堆叠,形成清晰的纵向两段式色块。
  3. 修改前后唯一的差异就是这一条声明,充分说明 display: flex 只负责“开启弹性上下文”,而真正的行/列排布由 flex-direction 决定。

顺带一提,若把值换成 column-reverse,两个盒子会交换上下顺序(橘红色块在上、蓝色块在下),这属于后续可自行验证的延伸实验。

自动判题如何验证你的答案

freeCodeCamp 对这类 HTML/CSS 练习采用浏览器内运行时测试。本课的 # --hints-- 区块给出了唯一一条判定规则:

const boxContainer = document.querySelector('#box-container');
const flexDirection = window.getComputedStyle(boxContainer)['flex-direction'];
assert.strictEqual(flexDirection, 'column');

这段测试代码的验证链路值得拆解:

  • document.querySelector('#box-container') 定位被测元素;
  • window.getComputedStyle(boxContainer)['flex-direction'] 读取该元素最终计算样式(computed style),即使 flex-direction 是通过样式表而非内联样式写入的也能正确读到;
  • assert.strictEqual(flexDirection, 'column') 做严格相等断言——若你没有添加该声明,计算值会是默认的 row,测试即失败;只有显式设为 column 才通过。

从实现角度印证:本课 frontmatter 中的 challengeType: 0 对应共享配置 packages/shared/src/config/challenge-types.ts 中的 html 类型,而该类型在配置中映射为 classic 运行方式与 tests 判题模式,即这种“提交 HTML/CSS 后由浏览器执行断言”的交互练习。同时,课程仓库用 curriculum/schema/challenge-schema.js 对挑战文件的字段做 Joi 校验,其中 hintsseedsolutions 均为受约束的规范结构,保证每个挑战都能被统一的解析与执行管线处理。

参考实现

挑战文件末尾的 # --solutions-- 区块提供了官方参考答案,与本课的完整实现一致:

<style>
  #box-container {
    display: flex;
    height: 500px;
    flex-direction: column;
  }
  #box-1 {
    background-color: dodgerblue;
    width: 50%;
    height: 50%;
  }

  #box-2 {
    background-color: orangered;
    width: 50%;
    height: 50%;
  }
</style>

<div id="box-container">
  <div id="box-1"></div>
  <div id="box-2"></div>
</div>

举一反三:在真实组件中把内容排成列

掌握了原理后,可以把同样的手法用于真实界面元素。紧邻本课的下一个挑战 587d78ac367417b2b2512af5.md 就要求在一个仿 Twitter 推文卡片中,对头部左侧的 .profile-name 元素(内含昵称 <h3> 与账号 <h4> 两行文字)设置 flex-direction: column,让“姓名在上、账号在下”自然纵向排列:

header .profile-name {
  display: flex;
  flex-direction: column;
  margin-left: 10px;
}

该元素的判题同样通过 window.getComputedStyle(profileName)['flex-direction'] 断言其等于 column。注意其父级 header 依旧保持 flex-direction: row——这正是 flexbox 的常见用法:外层容器负责把头像、名称区、Follow 按钮排成一行,内层 .profile-name 再独立开辟自己的纵向上下文,嵌套容器各自声明方向互不干扰。

挑战文件格式解剖:作者视角的补充

对于想了解 freeCodeCamp 课程文件机制的读者,本课文件本身就是一份完整的最小样例,其 Markdown 结构如下:

  • frontmatter:包含 idtitlechallengeTypevideoUrlforumTopicIddashedName 等元数据;schema 校验规定 dashedName 必须匹配 ^[a-z0-9-]+$(见 curriculum/schema/challenge-schema.js 中的 slugRE),forumTopicId 为数字、videoUrl 可为空字符串。
  • # --description--:用一两句话交代新知识点与前置知识的关系(本课指出“前两个挑战都用了 row”)。
  • # --instructions--:给出可执行的任务(添加并赋值 flex-direction)。
  • # --hints--:用真实浏览器断言定义“通过”标准,即本课前面展示的 getComputedStyle 检查。
  • ## --seed-contents--:学习者的起点代码,运行前由课程工具链解析、注入到可编辑页面。
  • # --solutions--:官方参考实现,用于对照与后续的自动化测试。

因此,本课既是一道面向初学者的 5 分钟小练习,也是一份结构规范、可被工具链解析与自动判题的“可执行文档”。若想继续巩固该系列知识,可以直接沿 css-flexbox 块 的挑战顺序学习后续的 justify-contentalign-itemsflex-wrap 等课程,最终完整掌握 flexbox 的一维布局能力。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391