首页
/ 深入解析 freeCodeCamp Bootstrap 挑战:用 col-xs-6 拆分栅格行(Split Your Bootstrap Row)

深入解析 freeCodeCamp Bootstrap 挑战:用 col-xs-6 拆分栅格行(Split Your Bootstrap Row)

2026-09-07 21:28:59作者:牧宁李

本文以 freeCodeCamp 开源课程中 Bootstrap 模块的第 22 个挑战 Split Your Bootstrap Row挑战原文件)为核心,系统讲解 Bootstrap 3 栅格系统中 row 与列(column)的搭配方式、col-xs-6 的宽度计算原理,同时结合仓库内 challenge 文件的 YAML 结构、校验 Schema 与自动化测试断言,帮助读者既能在课程中顺利通关,也能真正理解 Bootstrap 栅格背后的布局机制,并看懂 freeCodeCamp 挑战题是如何编写与校验的。

一、挑战背景:正在拼装的 jQuery Playground

在进入本挑战之前,我们需要先弄清它在整个课程块中的位置。打开 bootstrap 块的结构清单 可以看到,bootstrap 块的 helpCategoryHTML-CSSblockLayoutlegacy-challenge-list,其中 required 字段声明了本块所有挑战运行时的外部依赖——通过 CDN 引入的 twitter-bootstrap/3.3.7/css/bootstrap.css。也就是说,整个 Bootstrap 模块基于 Bootstrap 3.3.7 完成。

challengeOrder 数组可以看出一个清晰的"搭积木"式教学序列:

  1. Use Responsive Design with Bootstrap Fluid ContainersHouse our page within a Bootstrap container-fluid div —— 用 container-fluid 包住页面,保证移动端自适应;
  2. Create a Bootstrap Headline —— 创建带 text-primary text-centerh3 标题;
  3. Create a Bootstrap Row —— 在标题下方创建 div.row
  4. Split Your Bootstrap Row(本文主题) —— 将这一行拆成两列;
  5. Create Bootstrap WellsAdd Elements within Your Bootstrap Wells …… —— 在每一列中放入 well 容器并逐步填充内容。

这些步骤最终拼装成一个日后用于 jQuery 教学的交互小页面(jQuery Playground)。本挑战的角色正是承上启下的"分列"一步:上一挑战(Create a Bootstrap Row)把内容装进 row,而本挑战要把 row 内部划分为两个并排的 col-xs-6 列,为下一步 Create Bootstrap Wells 在每列中嵌套内容做准备。

二、任务目标拆解:row 内部建两个 col-xs-6

挑战描述原文要求:

Now that we have a Bootstrap Row, let's split it into two columns to house our elements. Create two div elements within your row, both with the class col-xs-6.

即:在现有 row div 内部创建 两个 div 元素,且两者都带有 col-xs-6,让它们并排承载后续内容。

挑战给定的起始代码(--seed-contents-- 段)如下:

<div class="container-fluid">
  <h3 class="text-primary text-center">jQuery Playground</h3>
  <div class="row">


  </div>
</div>

可以看到整体 DOM 骨架为 container-fluid(全宽流体容器)→ h3 标题 → row(栅格行),而 row 内部目前是空的。我们所需的全部改动,就是往空的 row 中补上两个带 col-xs-6div

三、栅格原理:为什么 col-xs-6 恰好是"一行两列"

要真正理解本挑战而不只是"照抄答案",需要明白 Bootstrap 3 的 12 栏栅格(grid)系统:

  • Bootstrap 3 把每一行(.row)横向划分为最多 12 列
  • 列宽通过 col-断点前缀-跨度 形式的类控制,前缀 xs / sm / md / lg 代表不同的屏幕尺寸档位;
  • 在本项目实际使用的 Bootstrap 3.3.7(见 bootstrap.jsonrequired 声明的 CSS 地址)中,xs 对应"极小屏幕及以上",其列样式不依赖任何媒体查询,即基础默认生效的规则;
  • col-xs-6 的含义是"占用 12 栏中的 6 栏",即 6 / 12 = 50% 宽度。两个 col-xs-6 并列时恰好铺满整行,形成左右各半的两栏布局。

因此本挑战的解法本质是:把 row 这个"12 栏"横向切成两份,每份 6 栏,从而并排安置两个将来要放内容的列容器。

四、标准解法与逐步推演

--solutions-- 段给出的官方标准答案如下:

<div class="container-fluid">
  <h3 class="text-primary text-center">jQuery Playground</h3>
  <div class="row">
    <div class="col-xs-6"></div>
    <div class="col-xs-6"></div>
  </div>
</div>

对照原始 seed,逐层核对:

层级 元素 作用
1 div.container-fluid 全宽流体容器,让内容适配任意屏幕宽度
2 h3.text-primary.text-center 标题(上一挑战产物,保持不动)
3 div.row 栅格行,规定横向 12 栏的布局上下文
4 div.col-xs-6 × 2 两列,各占 6/12 = 50% 宽度,左右并排

在动手时可借助"缩进即嵌套关系"的技巧自查:两个 col-xs-6 必须作为 row直接子元素出现,并且全部标签成对闭合(<div></div> 一一对应)。完成本挑战并跑通后,下一挑战会要求在每个 col-xs-6 内部再嵌套一个 div.well,形成"列中套容器"的更深一层结构。

五、验证标准(hints)逐条解读

freeCodeCamp 的每个挑战都可以看作一份带自动化校验的"教学测试用例"。本挑战的 --hints-- 段用 JavaScript 断言规定了验收标准,理解它们有助于反过来把握 Bootstrap 栅格结构的约束。

提示 1:结构约束——列必须嵌套在行内

assert.lengthOf(document.querySelectorAll('div.row > div.col-xs-6'),2);

该断言使用 CSS 子选择器 div.row > div.col-xs-6 精确匹配 row直接子级 col-xs-6,并要求数量为 2。这意味着:

  • 两个列元素必须用 class="col-xs-6"(不能是别的宽度类);
  • 它们必须是 row 的直接子元素,多包一层中间 div 会导致选择器失配;
  • 恰好两个,缺一个或多一个都无法通过。

提示 2:标签闭合完整性

assert.match(code,/<\/div>/g);
assert.match(code,/<div/g);
assert.equal(code.match(/<\/div>/g).length , code.match(/<div/g).length);

这里把用户的源码当作文本,分别用正则在整段代码中统计 <div</div> 的出现次数,并要求二者相等。结合前面几关(如 container-fluid 挑战Create a Bootstrap Row)中完全一致的断言写法可以看出,这一规则是整套 HTML 类挑战的通用卫生检查,专门用来防止用户写出未闭合的 div 标签。

六、挑战文件的内部结构:一份可学习的 YAML 模板

本挑战所在的 md 文件本身就是 freeCodeCamp 课程内容的"源数据格式"。理解它的结构,等于同时学会了阅读或编写课程块里任意一道同类挑战:

---
id: bad87fee1348bd9aec908847
title: Split Your Bootstrap Row
challengeType: 0
forumTopicId: 18306
dashedName: split-your-bootstrap-row
---

各字段含义如下:

  • id:挑战全局唯一标识,同时被 bootstrap.jsonchallengeOrder 引用,用于把挑战组织进块内顺序;
  • title:在课程导航、题目界面中展示的标题;
  • challengeType:挑战类型编号。在 challenge-types.tsconst html = 0,即本挑战属于纯 HTML 类(type 0);
  • forumTopicId:关联的社区论坛话题 ID,属于历史遗留字段;
  • dashedName:URL 化的 slug 形式标题(小写字母 + 连字符)。

Front matter 之下依次是四个用 Markdown 标题切分的正文段落:

  • # --description--:题目说明(含任务描述,可能内嵌示例);
  • # --hints--:验收断言列表,每条 hint 是一段说明文字 + 一段可执行的 JS 代码;
  • # --seed-- / ## --seed-contents--:编辑器初始代码;
  • # --solutions--:官方参考解法。

这些字段并非随意约定。仓库中的 challenge-schema.js 使用 Joi 对每道挑战做结构化校验,例如 challengeType 被限定为 0~33 的数字、dashedName 必须匹配 slug 正则、forumTopicId 为数字等。这也是 freeCodeCamp 能保证上万道挑战格式统一、可被构建管线稳定消费的底层机制之一。

七、运行与验证方式

Bootstrap 块已通过 bootstrap.jsonrequired 声明自动注入 Bootstrap 3.3.7 样式,因此只需把 HTML 内容粘贴到课程自带的编辑器即可实时预览;两个 col-xs-6 会让后续要放入的两个内容区块并排各占半行。若想在本地独立验证栅格效果,可新建一个 HTML 页面,在 <head> 中引入与课程一致的样式表并放入上述解法代码,将浏览器窗口从宽缩窄即可观察到两列始终保持 50% 等宽布局(因为 xs 档位没有最小宽度门槛)。

八、小结

Split Your Bootstrap Row 表面上只是一个"加两个 div"的小练习,但其背后串联了三层知识:

  1. 栅格使用姿势.row 必须位于容器内,列必须是 .row 的直接子元素,列跨度之和为 12 时恰好铺满一行;
  2. 断点前缀语义col-xs-6 在 Bootstrap 3 中代表"默认始终生效、占 6/12 宽度",是理解 sm/md/lg 等响应式档位的前提;
  3. 挑战工程化校验:通过 challenges 原始 md 文件 中 hints 的 DOM 断言与标签闭合断言,可以看到 freeCodeCamp 如何把一道 HTML 题目转译成可自动判分的测试用例。

掌握"容器—行—列"这三层结构与 12 栏分配逻辑后,继续阅读下一个挑战 Create Bootstrap Wells 时,你会自然理解为什么 well 必须被嵌进 col-xs-6 内部——因为列才是 Bootstrap 栅格中真正承载内容的布局单元。

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

项目优选

收起
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
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
594
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
916
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
516
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388