首页
/ freeCodeCamp 课程实战:用 CSS Transform 的 skewY() 沿 Y 轴倾斜元素

freeCodeCamp 课程实战:用 CSS Transform 的 skewY() 沿 Y 轴倾斜元素

2026-09-06 13:55:04作者:田桥桑Industrious

本文基于 freeCodeCamp 课程中 "Applied Visual Design"(应用视觉设计)板块的一道编辑器挑战题展开。该题目要求使用 transform 属性的 skewY() 函数将元素沿垂直(Y)轴倾斜 -10 度。读完本文,你将理解剪切(skew)变换的几何原理、skewX()/skewY() 的差异与角度正负号的视觉效果,并完整掌握这道题的初始代码、标准答案,以及 freeCodeCamp 是如何用断言测试来验证你的代码的。

一、这道题在课程中的位置

该挑战题的源文件是 curriculum/challenges/english/blocks/applied-visual-design/587d78a6367417b2b2512adc.md,其标题为 "Use the CSS Transform Property skewY to Skew an Element Along the Y-Axis"(使用 CSS Transform 属性 skewY 沿 Y 轴倾斜元素)。

从课程结构文件 applied-visual-design.json 可以看到该题在板块中的精确顺序:

{
  "id": "587d78a6367417b2b2512adb",
  "title": "Use the CSS Transform Property skewX to Skew an Element Along the X-Axis"
},
{
  "id": "587d78a6367417b2b2512adc",
  "title": "Use the CSS Transform Property skewY to Skew an Element Along the Y-Axis"
},
{
  "id": "587d78a6367417b2b2512add",
  "title": "Create a Graphic Using CSS"
}

也就是说,它紧跟在 skewX() 练习之后——课程先用 X 轴倾斜建立直觉,再过渡到 Y 轴倾斜,随后就进入"用 CSS 制作图形"的综合性练习。该板块属于 applied-visual-design(helpCategory 为 HTML-CSS),隶属于 Responsive Web Design 认证,这一点可以从 responsive-web-design.json 的结构中确认。

二、skewY():沿垂直轴的剪切变换

原题目的描述(description)部分写道:既然 skewX() 会沿 X 轴倾斜元素,那么 skewY() 就是沿 Y(垂直)轴倾斜元素。

两者的几何含义是:

函数 作用轴 视觉表现
skewX(angle) 水平(X)轴 上下两条水平边保持原位,左右两侧向相反方向水平错位,元素被"横着压扁"
skewY(angle) 垂直(Y)轴 左右两条垂直边保持原位,上下两侧向相反方向垂直错位,元素被"竖着压扁"

从源码结构看,skew 类变换属于 CSS 的剪切(shear)变换:变换只移动每个像素点,移动量与该点到变换原点(transform-origin)在垂直于剪切轴方向上的距离成正比,即位移 = tan(角度) × 距离。因此:

  • 角度绝对值越大,错位越明显;skewY(90deg) 在数学上已经是奇异状态(tan 趋于无穷),实际角度通常取 ±45° 以内的较小值;
  • 正负号决定倾斜方向skewY(-10deg) 会让元素上方向右、下方向左倾斜(以默认的 transform-origin: 50% 50% 计),而 skewY(10deg) 则方向相反;
  • 变换不改变元素在文档流中占据的布局盒大小,只改变渲染结果——这和 scale()rotate() 一样,是纯视觉变换。

CSS 还提供了一个双参数简写 skew(a, b),第一个参数作用于 X 轴,第二个作用于 Y 轴,例如 skew(0deg, -10deg)skewY(-10deg) 效果等价。

三、题目任务与初始代码(seed)

任务要求(instructions)原文:使用 transform 属性,将 id 为 top 的元素沿 Y 轴倾斜 -10 度。

题目的初始编辑器代码(seed-contents)如下:

<style>
  div {
    width: 70%;
    height: 100px;
    margin: 50px auto;
  }
  #top {
    background-color: red;

  }
  #bottom {
    background-color: blue;
    transform: skewX(24deg);
  }
</style>

<div id="top"></div>
<div id="bottom"></div>

初始代码中有几个值得注意的铺垫:

  1. 公共样式:两个 div 都是 width: 70%height: 100px,并用 margin: 50px auto 水平居中,保证对比效果清晰;
  2. #bottom 已经写好了 transform: skewX(24deg);——这是上一道 skewX 挑战题 的答案,在此作为参照物保留;
  3. #top 只有背景色、没有 transform(注意其花括号内有一个空行),这正是你需要补上 transform: skewY(-10deg); 的位置。

四、完整答案与逐行解析

题目的标准答案(solutions)完整代码如下:

<style>
  div {
    width: 70%;
    height: 100px;
    margin: 50px auto;
  }
  #top {
    background-color: red;
    transform: skewY(-10deg);
  }
  #bottom {
    background-color: blue;
    transform: skewX(24deg);
  }
</style>
<div id="top"></div>
<div id="bottom"></div>

相对初始代码,唯一的变化就是在 #top 规则中加入了一行:

transform: skewY(-10deg);

渲染后,红色的 #top 矩形会被沿垂直轴轻微"歪斜",与下方被横向剪切 24 度的蓝色 #bottom 矩形形成对照,直观展示了两种剪切方向的区别。

几个易错点:

  • 必须写在 #top 的选择器内,且属性名是 transform(不能写成已废弃的 -webkit-transformskewY: 之类的属性);
  • 角度必须精确为 -10deg,缺少负号(写成 skewY(10deg))或单位(写成 skewY(-10))都会被判定为不满足要求;
  • transform 是"整体替换"语义:如果在同一选择器里再写另一个 transform,后写的会覆盖前面的,多个变换应写在同一声明里,如 transform: skewY(-10deg) rotate(5deg);(从右向左依次应用)。

五、测试如何验证你的答案:hints 中的断言正则

题目 hints 部分给出了一条断言:

assert.match(code, /#top\s*?{\s*?.*?\s*?transform:\s*?skewY\(-10deg\);/g);

这条正则精确刻画了通过判定:

  • #top\s*?{ —— 匹配 #top 选择器及其开始花括号(\s*? 是非贪婪空白匹配,容忍任意排版空格);
  • .*? —— 允许中间存在其他声明(如 background-color: red;);
  • transform:\s*?skewY\(-10deg\); —— 关键部分:transform 属性后必须紧跟 skewY(-10deg),括号与连字符在正则中都做了转义(\(-10deg)。

这也解释了为什么答案里 #top 必须先保留 background-color 再追加 transform——断言允许两者之间的任意内容,但顺序必须是选择器 → 若干声明 → transform: skewY(-10deg);

六、挑战题的数据结构:从 Markdown 到编辑器

这道题的文件本身就是一份带 frontmatter 的 Markdown,其字段与课程模式 challenge-schema.js 中的 Joi 校验相对应:

---
id: 587d78a6367417b2b2512adc
title: Use the CSS Transform Property skewY to Skew an Element Along the Y-Axis
challengeType: 0
dashedName: use-the-css-transform-property-skewy-to-skew-an-element-along-the-y-axis
forumTopicId: 301075
---

各字段含义:

  • id:与文件名一致,同时出现在 applied-visual-design.jsonchallengeOrder 中,用于把题目挂到板块顺序里;
  • challengeType: 0:编辑器挑战题。从 challenge-schema.js 可见 challengeType 被限定为 0 到 33 的整数(Joi.number().min(0).max(33)),不同类型对应不同的题目形态(编辑器题、视频、多选、填空等);
  • dashedName:由标题生成的 URL 友好 slug,必须匹配小写字母数字与连字符(slugRE = /^[a-z0-9-]+$/)。

正文部分由约定标记的区段组成:# --description--(讲解)、# --instructions--(任务)、# --hints--(提示与断言)、## --seed-contents--(初始代码)、# --solutions--(参考答案)。课程构建管线会解析这些区段生成挑战数据,--seed-contents-- 中的代码即渲染进在线编辑器的初始内容,--hints-- 中的断言即提交时的判题逻辑。

七、skew 在后续课程中的进阶应用

skew 并不只出现在这一道练习题里。在仓库课程中,"Learn CSS Transforms by Building a Penguin" 项目(learn-css-transforms-by-building-a-penguin 板块)以及 "Flappy Penguin" 工作坊的几十个挑战文件里都大量使用了 transform: skewrotatescale 的组合来塑造图形——可以推断,skewY 这类剪切变换是后续 CSS 图形项目的常规工具。

理解 skewY(-10deg) 时的建议路径:

  1. 先跑通本题:在 #top 中补上 transform: skewY(-10deg);,对照红蓝两个矩形的倾斜方向;
  2. 改动角度与正负号:试试 skewY(10deg)skewY(-30deg),观察倾斜方向与程度如何变化;
  3. 加入 transform-origin:例如 transform-origin: 0 0;,观察剪切锚点变化对整体位移的影响;
  4. 组合多个变换:transform: skewY(-10deg) rotate(90deg);,体会变换函数的作用顺序。

小结

本文以 freeCodeCamp "Applied Visual Design" 板块中的 skewY 挑战题为线索,覆盖了:skewX()/skewY() 的几何原理与角度、正负号语义;题目完整的初始代码与标准答案(在 #top 规则中补写 transform: skewY(-10deg););判题断言正则 /#top\s*?{\s*?.*?\s*?transform:\s*?skewY\(-10deg\);/g 的匹配逻辑;以及题目背后的 Markdown 挑战文件结构(idchallengeTypedashedName 等字段与 Joi 模式校验)。掌握这些内容后,你既能独立通过这道课程题,也能把 skew 剪切变换用到自己的 CSS 图形与视觉设计实践中。

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

项目优选

收起
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