主题
移动 Web 基础与变换(三)
本页对应 移动 Web 基础与变换,共 7 段视频,约 1 小时 15 分。
学习目标
- 能使用
transform完成元素的平面位移、旋转与缩放,并正确设置位移、旋转的复合顺序,通过浏览器验证效果。 - 能使用
translate(-50%, -50%)等位移方案实现盒子在父容器中水平垂直居中。 - 能使用
linear-gradient编写指定方向和多颜色渐变的背景,并应用到综合案例中。 - 能解释
perspective视距的作用,使用translate3d、translateZ实现近大远小的空间位移效果。 - 能使用
rotateX/rotateY/rotateZ完成 3D 旋转,并依据左手法则判断正负角度对应的旋转方向。 - 能使用
transform-style: preserve-3d为父元素开启 3D 呈现,独立完成双面盒子或导航案例的 3D 展开效果。
知识点
平面转换总览
作用是为元素添加动态效果,一般与过渡配合使用;概念是改变盒子在平面内的形态:位移、旋转、缩放、倾斜。

- 为什么需要:让页面元素产生位移、旋转、缩放等视觉变化,而不是只改布局。
- 怎么想:平面转换也叫 2D 转换,核心属性是
transform;它改变的是“形态”,不是文档流位置。 - 怎么做:给元素写
transform,再配合transition看过渡效果。 - 易错点:
transform不是过渡;没有transition时变化会瞬间完成。转写稿“今日总结”也强调:平面转换重点掌握transform、位移、旋转、缩放和复合写法。
平移 translate
css
transform: translate(X轴移动距离, Y轴移动距离);- 取值:像素单位数值;百分比(参照盒子自身尺寸计算);正负均可。
- 技巧:
translate()只写一个值,表示沿 X 轴移动;单独设置用translateX()或translateY()。
为什么需要:做位移、悬停移动、定位居中。
怎么想:先判断动 X 还是 Y;百分比不是相对父级,而是相对自身宽高。转写稿总结也明确:值可写具体 PX,也可写百分数,百分数相对盒子自身宽高。
怎么做:如 transform: translate(100px, 50px);。
易错点:只写一个值是 X 轴;translate 不脱离文档流;百分比参照自身。
定位居中
方法一:margin。

方法二:平移,百分比参照盒子自身尺寸计算结果。

为什么需要:绝对定位盒子居中很常见。
怎么想:先 left/top: 50% 到父级一半,再用 translate(-50%, -50%) 回退自身一半。
怎么做:
css
left: 50%;
top: 50%;
transform: translate(-50%, -50%);易错点:这里的 -50% 是自身尺寸的一半,不是父级;若元素已有 transform,要注意合并写,避免覆盖。
案例-双开门

HTML 结构:
html
<div class="father">
<div class="left"></div>
<div class="right"></div>
</div>CSS 样式:
css
* {
margin: 0;
padding: 0;
}
/* 1. 布局:父子结构,父级是大图,子级是左右小图 */
.father {
display: flex;
margin: 0 auto;
width: 1366px;
height: 600px;
background-image: url(./images/bg.jpg);
overflow: hidden;
}
.father .left,
.father .right {
width: 50%;
height: 600px;
background-image: url(./images/fm.jpg);
transition: all .5s;
}
.father .right {
/* right 表示的取到精灵图右面的图片 */
background-position: right 0;
}
/* 2. 鼠标悬停的效果:左右移动 */
.father:hover .left {
transform: translate(-100%);
}
.father:hover .right {
transform: translateX(100%);
}为什么需要:综合练习平移、百分比和过渡。
怎么想:父级裁切,左右各占 50%,悬停时左门向左、右门向右。
怎么做:translate(-100%) 只写一个值表示 X 轴移动自身宽度。
易错点:父级要 overflow: hidden;过渡写在子级;右图要用 background-position: right 0。
旋转 rotate
css
transform: rotate(旋转角度);- 取值:角度单位是
deg。 - 技巧:正负均可;正值为顺时针,负值为逆时针。
为什么需要:做角度变化、时钟指针等。
怎么想:先确定旋转角度和正负。转写稿总结也强调:平面旋转正值为顺时针。
怎么做:transform: rotate(45deg);。
易错点:单位是 deg;旋转默认绕盒子中心,不改变布局。
转换原点 transform-origin
默认情况下,转换原点是盒子中心点。
css
transform-origin: 水平原点位置 垂直原点位置;取值:方位名词(left、top、right、bottom、center);像素单位数值;百分比。
为什么需要:让元素绕指定点旋转。
怎么想:先写水平位置,再写垂直位置。
怎么做:时钟指针要让底部中心作为原点。
易错点:transform-origin 写在被转换元素上;默认是 center center。
案例-时钟

css
.hour {
width: 6px;
height: 50px;
background-color: #333;
margin-left: -3px;
transform: rotate(15deg);
transform-origin: center bottom;
}
.minute {
width: 5px;
height: 65px;
background-color: #333;
margin-left: -3px;
transform: rotate(90deg);
transform-origin: center bottom;
}
.second {
width: 4px;
height: 80px;
background-color: red;
margin-left: -2px;
transform: rotate(240deg);
transform-origin: center bottom;
}为什么需要:练习旋转与转换原点。
怎么想:指针绕底部中心转,所以原点用 center bottom。
怎么做:分别设置宽高、颜色、旋转角度和原点。
易错点:原点不设置会绕中心转;margin-left 用于微调指针位置。
多重转换
多重转换技巧:先平移再旋转。
css
transform: translate() rotate();- 多重转换原理:以第一种转换方式坐标轴为准转换形态。
- 旋转会改变网页元素的坐标轴向;先写旋转,则后面的转换效果以旋转后的轴向为准,会影响结果。
为什么需要:一个元素同时移动和旋转。
怎么想:转写稿总结说,复合属性一般把位移写在旋转前面;如果旋转在前,轴会随旋转改变,移动容易乱。
怎么做:transform: translate(100px) rotate(45deg);。
易错点:顺序不同结果不同;不要随意调换。
缩放 scale
css
transform: scale(缩放倍数);
transform: scale(X轴缩放倍数, Y轴缩放倍数);- 技巧:通常只为
scale()设置一个值,表示 X 轴和 Y 轴等比例缩放;大于 1 放大,小于 1 缩小。
为什么需要:做放大缩小、悬停按钮。
怎么想:一个值等比缩放,不容易失调;转写稿总结也提到写一个值代表 X、Y 同比例。
怎么做:transform: scale(1.2);。
易错点:缩放不影响布局;scale(0) 不可见;与 translate 组合时注意顺序。
案例-播放特效

css
/* 1. 摆放播放按钮:图片区域的中间 */
.box li {
overflow: hidden;
}
.pic {
position: relative;
}
.pic::after {
position: absolute;
left: 50%;
top: 50%;
/* margin-left: -29px;
margin-top: -29px; */
/* transform: translate(-50%, -50%); */
content: '';
width: 58px;
height: 58px;
background-image: url(./images/play.png);
transform: translate(-50%, -50%) scale(5);
opacity: 0;
transition: all .5s;
}
/* 2. hover效果:大按钮,看不见:透明是0 → 小按钮,看得见:透明度1 */
.box li:hover .pic::after {
transform: translate(-50%, -50%) scale(1);
opacity: 1;
}为什么需要:综合平移居中、缩放和透明度。
怎么想:伪元素先居中,再放大到 5 倍且透明;悬停时回到 1 倍并显示。
怎么做:translate(-50%, -50%) scale(5) 到 scale(1)。
易错点:组合顺序要保持一致;父级 overflow: hidden 裁切溢出;过渡写在伪元素上。
倾斜 skew
css
transform: skew();取值:角度度数 deg。
为什么需要:做倾斜变形效果。
怎么想:与旋转不同,倾斜是让盒子边线倾斜。
怎么做:如 transform: skew(10deg);。
易错点:单位仍是 deg;倾斜也会受转换原点和组合顺序影响。
渐变总览:先判断“给谁看”
为什么需要: 纯色背景信息层次单一,渐变可以让盒子背景从一种颜色自然过渡到另一种颜色,常用于横幅、遮罩、按钮、卡片背景等。笔记明确:渐变是多个颜色逐渐变化的效果,一般用于设置盒子背景。
怎么想: 先分两类——线性渐变有“方向感”,颜色沿一条线变化;径向渐变有“中心感”,颜色从圆心向外扩散。两者都通过 background-image 设置,不是 background-color。


怎么做: 记住两类语法都包含“渐变类型 + 参数 + 至少两个颜色”。调试时可按转写稿里的思路:先写两个颜色确认渐变生效,再补方向或圆心;忘了就查、就试,它本质仍是 CSS 语法,不会跑出 CSS 的规则范围。
易错点: 不要把渐变写成 background-color;颜色至少两个;参数之间用逗号分隔;转写稿里“见面色”应理解为“渐变色”,“CSA钥匙”应理解为“CSS 语法/样式”,不要被同音字带偏。
线性渐变:方向与颜色停靠点
为什么需要: 当背景需要“从透明到黑”“从浅到深”“从暖到冷”的过渡时,线性渐变最直接,尤其适合做图片遮罩。
怎么想: 参数顺序是:渐变方向(可选)→ 颜色1 终点位置(位置可选)→ 颜色2 终点位置(位置可选)→ ……。方向可写 to 方位名词 或角度度数;终点位置可写百分比。转写稿也提到“第一个位置看来是可以省略的”,所以不确定方向时可以先省略,先保证颜色过渡成立。
怎么做:
css
background-image: linear-gradient(
渐变方向,
颜色1 终点位置,
颜色2 终点位置,
......
);取值:
- 渐变方向:可选
- to 方位名词
- 角度度数
- 终点位置:可选
- 百分比
易错点: 方向写在第一位,颜色和位置之间用空格;颜色之间用逗号;不要漏写 linear-gradient 的括号;调试顺序建议“先两色→再方向→再位置”。
案例-产品展示:用渐变做可读遮罩

为什么需要: 图片底部直接放白色标题,遇到浅色图片会看不清;全黑遮罩又太重。用“透明→半黑”的线性渐变,只压暗文字区域,既保留图片又提升可读性。
怎么想: 用 .mask 绝对定位铺满父盒,背景写 linear-gradient(transparent, rgba(0,0,0,0.5));默认 opacity: 0 隐藏,鼠标移入 .box 时 opacity: 1 显示,并加 transition 做柔和过渡。
怎么做:
- HTML 结构
html
<div class="box">
<img src="./images/product.jpeg" alt="" />
<div class="title">OceanStor Pacific 海量存储斩获2021 Interop金奖</div>
<div class="mask"></div>
</div>- CSS 样式
css
.mask {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-image: linear-gradient(
transparent,
rgba(0,0,0,0.5)
);
opacity: 0;
transition: all .5s;
}
.box:hover .mask {
opacity: 1;
}易错点: .mask 用了 absolute,实际完整页面中父级 .box 要有定位上下文(如 position: relative),否则会相对更外层定位;隐藏用 opacity 而不是 display: none,否则过渡不自然;transition 写在 .mask 上;rgba 最后一位是透明度。
径向渐变:从圆心向外扩散
为什么需要: 需要“中心亮、四周暗”或“圆形光晕”时,线性渐变方向太强,径向渐变更自然,适合做聚光灯、圆形高亮背景。
怎么想: 参数是:半径 at 圆心位置 → 颜色1 终点位置 → 颜色2 终点位置 → ……。半径可以写两条,写两条就是椭圆;圆心位置可写像素、百分比、方位名词。颜色终点位置仍可选百分比。
怎么做:
css
background-image: radial-gradient(
半径 at 圆心位置,
颜色1 终点位置,
颜色2 终点位置,
......
);取值:
- 半径可以是2条,则为椭圆
- 圆心位置取值:像素单位数值 / 百分比 / 方位名词
易错点: at 不能漏;半径和圆心位置顺序不要反;两条半径才是椭圆;颜色至少两个;圆心位置和颜色位置都是可选增强项,初学先保证“半径 + 两色”能跑通。
收尾检查:渐变调试顺序
为什么需要: 渐变参数长,容易漏逗号、漏 at、把 background-image 写成 background-color,按顺序检查最快。
怎么想: 先确认“是不是背景图语法”→再确认“至少两个颜色”→再补方向/圆心→最后做遮罩和 hover 交互。转写稿说“忘了直接去查,或者用的时候完全忘了,你再试就可以了”,这是很实用的调试态度。
怎么做: 用开发者工具逐项改参数:先改颜色看是否变化,再改方向/圆心看位置是否变化,最后调 opacity 和 transition 看交互是否顺滑。
易错点: 不要凭感觉堆参数;每次只改一个变量;案例中的 .mask 片段要结合完整父级样式使用;渐变是背景图,不是纯色背景。
综合案例效果与整体思路

本节把页面中的导航、按钮、轮播图和“猜你喜欢”等交互串起来。为什么需要:真实页面往往不是单一属性练习,而是多个小效果叠加;怎么想:先按区块拆结构,再分别处理 hover、定位、渐变、遮罩和变换;怎么做:下面按笔记代码逐块实现;易错点:定位元素的层级、过渡是否加上、hover 选择器是否写全,都会导致“代码写了但没效果”。
导航-频道:箭头旋转与下拉列表
为什么需要:导航 hover 时要有反馈,频道列表要平滑出现。怎么想:箭头用旋转表示展开,列表用绝对定位放在导航下方,再用 transform 做位移过渡。怎么做:箭头 hover 旋转,列表默认上移隐藏,hover 时回到 translateY(0)。
css
.x-header-nav .nav-item:hover .icon-down {
transform: rotate(-180deg);
}css
.channel-layer {
position: absolute;
top: 60px;
left: 50%;
z-index: -2;
width: 1080px;
height: 120px;
padding: 10px;
margin-left: -540px;
color: #72727b;
background-color: #f5f5f5;
border: 1px solid #e4e4e4;
border-top: none;
transition: all 0.5s;
transform: translateY(-120px);
}
/* TODO 2. 弹窗频道 */
.x-header-nav .nav-item:hover .channel-layer {
transform: translateY(0);
}易错点:left:50% 要配合 margin-left:-540px 居中;z-index:-2 与父级层级有关,若被遮挡要检查父元素是否创建了层叠上下文;过渡要写在默认状态上。
渐变按钮:搜索、登录、客户端
为什么需要:按钮要有立体感和品牌色。怎么想:搜索按钮用线性渐变叠加圆角,登录按钮加阴影和线性渐变,客户端按钮用径向渐变做高光。怎么做:分别设置背景色、圆角和 background-image。
css
.x-header-search form .btn {
position: absolute;
top: 0;
right: 0;
width: 60px;
height: 40px;
line-height: 40px;
text-align: center;
background-color: #f86442;
border-top-right-radius: 20px;
border-bottom-right-radius: 20px;
background-image: linear-gradient(
to right,
rgba(255, 255, 255, 0.3),
#f86442
);
}css
/* TODO 7. 渐变按钮 */
.card .card-info .login {
padding: 3px 34px;
color: #fff;
background-color: #ff7251;
border-radius: 30px;
box-shadow: 0 4px 8px 0 rgb(252 88 50 / 50%);
background-image: linear-gradient(
to right,
rgba(255, 255, 255, 0.2),
#ff7251
);
}css
/* TODO 8. 径向渐变 */
.download .dl .dl-btn {
width: 68px;
height: 34px;
line-height: 34px;
color: #fff;
text-align: center;
border-radius: 4px;
background-image: radial-gradient(
50px at 10px 10px,
rgba(255, 255, 255, 0.5),
transparent
);
}易错点:渐变会覆盖 background-color 的视觉表现,但保留底色可作兜底;径向渐变的圆心和半径要写清,否则高光位置不对。
轮播图:左右图片的层叠与缩放
为什么需要:轮播图非当前项要退到两侧,形成空间层次。怎么想:用 translate 平移、scale 缩小,并用 transform-origin 控制缩放基准。怎么做:左右项分别向两侧位移并缩小,z-index:0 压到主图后面。
css
/* TODO 4. 摆放图片 */
.banner .banner-list .banner-item.left {
z-index: 0;
transform: translate(-160px) scale(0.8);
transform-origin: left center;
}
.banner .banner-list .banner-item.right {
z-index: 0;
transform: translate(160px) scale(0.8);
transform-origin: right center;
}易错点:transform-origin 不写会默认中心缩放,左右贴边效果会变;多个变换写在同一 transform 中,顺序会影响结果。
猜你喜欢:播放遮罩与图片缩放
为什么需要:鼠标悬停时提示可播放,并让图片有轻微放大反馈。怎么想:用 ::after 做遮罩和播放图标,默认透明,hover 时显示;图片 hover 时 scale(1.1)。怎么做:遮罩绝对定位覆盖盒子,背景图用 url(../assets/play.png) 居中。
css
/* TODO 5. 播放按钮和遮罩 */
.album-item .album-item-box::after {
position: absolute;
left: 0;
top: 0;
content: '';
width: 100%;
height: 100%;
background: rgba(0,0,0,.5) url(../assets/play.png) no-repeat center / 20px;
opacity: 0;
transition: all .5s;
}
.album-item .album-item-box:hover::after {
opacity: 1;
background-size: 50px;
}
/* TODO 6. 图片缩放 */
.album-item .album-item-box:hover img {
transform: scale(1.1);
}易错点:::after 要加 content:'' 才显示;父盒子要设 position:relative 才能让遮罩相对它定位;图片放大要防止溢出,通常给父盒子加 overflow:hidden。
用转写稿补 3D 推导:视距、3D 呈现与左手法则
为什么需要:理解 3D 变换能解释导航案例中“近大远小”和“父元素开 3D 空间”的问题。怎么想:Z 轴正方向是垂直屏幕向外、朝眼睛;只写 translate3d 看不到近大远小,是因为没开视距;子元素做 3D 变换不生效,是因为父元素没开 3D 呈现。怎么做:给 body 加 perspective 开启视距,常用范围约 800–1200,值越小变化越猛烈;给父元素加 transform-style: preserve-3d 开启 3D 空间;旋转正负用左手法则判断:大拇指指向所选轴正方向,其余手指弯曲方向为正角度方向。易错点:translateZ 用百分数没有效果,因为盒子没有“厚度”可作参考;视距不是加给子元素而是加给父级/body;3D 呈现必须加给要做 3D 变换子元素的父元素。转写稿中的调试过程也说明:先写位移看不出 Z 轴,补视距后才出现“离得近变大”;两个面一前一后叠放时,必须给父级开 3D 呈现,否则子元素仍像平面叠加。
代码示例
示例一:3D 位移 + 视距(perspective)
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>3D位移与视距</title>
<style>
* {
margin: 0;
padding: 0;
}
/* 视距:一般加给 body(最大的父级),用于开启近大远小的透视效果 */
body {
perspective: 600px;
}
.box {
width: 200px;
height: 200px;
margin: 100px auto;
background-color: pink;
transition: all .5s;
}
/* 三个方向同时移动:X 100px、Y 100px、Z 100px */
.box:hover {
transform: translate3d(100px, 100px, 100px);
}
/* 也可以单独体验某个方向:
.box:hover { transform: translateX(300px); } // 平面移动,不会变大
.box:hover { transform: translateZ(100px); } // 离眼睛更近 → 变大
.box:hover { transform: translateZ(-100px); } // 离眼睛更远 → 变小
*/
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>要点解释与易错点:
perspective加在 body(最大父级) 上,作用是开启“近大远小”的透视效果;值越小,盒子变化越猛烈(600、300 很夸张),值越大越平缓(如 2000 几乎看不出变化)。- 只有
translateZ()才能体现“近大远小”,translateX()/translateY()是平面内移动,盒子不会变大变小。 - 不给 body 加
perspective时,translateZ()写了也看不到任何效果——这是最容易踩的坑。 - 易错点:
translateZ(100%)写法语法没问题,但没有效果,因为百分比要参照盒子自身尺寸,而盒子只有宽和高、没有厚度,参照值为 0。
示例二:3D 旋转(绕 X / Y / Z 轴)
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>3D旋转</title>
<style>
* {
margin: 0;
padding: 0;
}
/* 开视距,否则看不出空间旋转的立体感 */
body {
perspective: 600px;
}
.box {
width: 200px;
height: 200px;
margin: 100px auto;
background-color: pink;
transition: all .3s;
}
/* 绕 X 轴旋转(左手法则判断正负) */
.box:hover {
transform: rotateX(60deg);
}
/* 其他三种写法,可逐个替换上面的 transform 体验:
.box:hover { transform: rotateY(60deg); } // 绕 Y 轴
.box:hover { transform: rotateZ(360deg); } // 绕 Z 轴(等同平面旋转)
.box:hover { transform: rotate3d(1, 1, 0, 60deg); } // 自定义轴
*/
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>要点解释与易错点:
- 3D 旋转必须明确“绕哪根轴转”,语法是
rotateX()/rotateY()/rotateZ(),单位是deg。 rotateZ()就是平面旋转,不加 perspective 也能看到效果;但rotateX()/rotateY()是空间旋转,最好配合perspective才明显。- 左手法则判断正负:左手大拇指指向该轴的正方向,其余四指弯曲的方向就是正值的旋转方向;负值反向即可。
- 易错点:不要靠背“正负哪个转哪边”,一旦轴换了就容易乱;先确定轴的正方向,再用左手法则判断。
rotate3d(x, y, z, deg)前三个值是自定义轴的终点坐标(相当于空间坐标),如1,1,0表示轴在平面内斜 45° 方向;这是了解性内容,工作中极少使用。
示例三:3D 呈现(preserve-3d)——两个面一前一后
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>3D呈现</title>
<style>
* {
margin: 0;
padding: 0;
}
/* 视距:开启近大远小 */
body {
perspective: 600px;
}
.father {
/* 定位参照,让子元素叠在一起 */
position: relative;
width: 200px;
height: 200px;
margin: 100px auto;
border: 1px solid #000;
/* 关键:子元素要做 3D 转换,必须给父元素开启 3D 呈现 */
transform-style: preserve-3d;
transition: all .3s;
}
/* 父盒子整体绕 Y 轴旋转,才能看到两个面岔开的空间感 */
.father:hover {
transform: rotateY(60deg);
}
.father div {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 200px;
}
/* 第一个面:沿 Z 轴正方向往前走 100px(宽的一半) */
.one {
background-color: red;
transform: translateZ(100px);
}
/* 第二个面:沿 Z 轴负方向往后走 100px */
.two {
background-color: blue;
transform: translateZ(-100px);
}
</style>
</head>
<body>
<div class="father">
<div class="one"></div>
<div class="two"></div>
</div>
</body>
</html>要点解释与易错点:
- 思路三步走:① 父盒子 + 两个子盒子;② 子盒子用
position: absolute; left: 0; top: 0;归位叠在一起(同一个起点出发);③ 一个translateZ(100px)往前、一个translateZ(-100px)往后,形成一前一后的空间关系。 - 前后移动的距离取盒子宽(高)的一半,才能拼成标准立方体的两面。
- 最关键的易错点:只写
translateZ()是不生效的,必须给直接父元素加transform-style: preserve-3d;,相当于给子元素开放 3D 空间权限。 - 蓝色面在后面被红色面挡住是正常的,鼠标悬停让父盒子整体旋转才能看到两个面岔开的效果。
- 父盒子的
border只是为了方便观察父级位置,正式使用时通常去掉。
常见错误
1. 用 translate(-50%, -50%) 做居中,盒子偏移量明显不对
- 现象:定位居中后盒子偏出容器一半甚至更多,改
left/top也调不准。 - 原因:把百分比当成"相对父盒子宽高"来算,实际
translate的百分比参照的是元素自身的宽高。 - 修法:确认
left:50%; top:50%与translate(-50%,-50%)成对出现;若元素宽高由内容撑开,先固定尺寸再验证。
2. 双开门 / 悬停联动效果只动了一边
- 现象:鼠标移到左门上只有左门开,右门不动;或移入子元素瞬间效果消失闪烁。
- 原因:
:hover挂在了子元素上(.left:hover),而不是父容器上。 - 修法:选择器写成
.father:hover .left、.father:hover .right,让父级状态驱动所有子元素。
3. 多重转换顺序写反,位移方向"歪"了
- 现象:
transform: rotate(45deg) translateX(100px)的位移没有沿水平方向,而是斜着走。 - 原因:后写的转换以先写转换改变后的坐标轴为准,旋转已把 X 轴转歪。
- 修法:位移一律写在旋转之前——
transform: translateX(100px) rotate(45deg)。
4. transform-origin 只写一个值,时钟指针绕中心转
- 现象:写了
transform-origin: bottom,指针仍然绕自身中心旋转,一端甩出表盘。 - 原因:单值只作用于水平方向,垂直方向仍默认
center。 - 修法:写两个值
transform-origin: center bottom;调完用 DevTools 看原点标记是否落在指针根部。
5. 子元素 translateZ() 完全没反应
- 现象:给子盒子写
translateZ(100px),页面毫无变化,元素也不变大。 - 原因:一是父级没开
perspective(无近大远小);二是父级没写transform-style: preserve-3d,3D 空间被压平。 - 修法:
perspective加在 body 或父级上,transform-style: preserve-3d加在直接父级上,两者都到位再看效果。
6. translateZ(100%) 写不出错但没效果
- 现象:百分比形式的 Z 轴位移无任何变化,也不报错。
- 原因:百分比需要参照元素自身对应方向尺寸,而盒子没有"厚度",参考值为 0。
- 修法:Z 轴位移统一用 px;只有 X/Y 轴才考虑百分比。
7. 渐变写在 background-color 上不生效
- 现象:
background-color: linear-gradient(...)整条样式被浏览器判为无效,背景是透明或纯色。 - 原因:渐变本质是一张图片,不是颜色。
- 修法:改用
background-image(或background简写);若同时需要底色,background-color保留作降级。
练习
练习 1|居中三选一 分别用 margin 负值法、translate(-50%,-50%) 法实现同一个 200×120 盒子的容器居中,把容器宽高改成 400×300 后再看两种写法是否需要改代码,记录差异。
练习 2|双开门 + 反向验证 完成双开门案例后,故意把 .father:hover .left 改成 .left:hover,观察现象并说明原因;再恢复。另外把 translate(-100%) 改成 translateX(-100px),比较门扇开合是否与自身宽度匹配。
练习 3|时钟指针 用三个 div 做时/分/秒针,只允许改 transform 和 transform-origin,让三根针分别指向 3 点、6 点、9 点方向,并保证旋转时始终绕针尾。
练习 4|播放按钮放大进场 实现"小按钮→大按钮淡入"的 hover 效果,要求初始 scale(5) + opacity:0,hover 时 scale(1) + opacity:1,且按钮中心始终对齐图片中心。完成后把 translate 和 scale 顺序对调,观察按钮位置是否偏移。
练习 5|3D 翻折导航条 用一个父盒 + 两个等大子盒,做出"正面 + 顶面"的结构:子盒先重叠归位,一个沿 Z 轴前移,另一个上移后绕 X 轴转 90° 躺平,最后父盒 hover 时整体绕 X 轴旋转展示立体结构。中途若某一步没效果,逐一检查 perspective、preserve-3d 是否加在正确的元素上。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 3D位移-1-基本 | 11:46 |
| 2 | 3D位移-2-视距了解 | 07:45 |
| 3 | 3D旋转-1-基本 | 08:57 |
| 4 | 3D旋转-2-拓展自定义轴 | 08:12 |
| 5 | 3D呈现-1-基本 | 14:04 |
| 6 | 3D呈现-2-导航案例 | 13:42 |
| 7 | 今日总结 | 11:23 |
小结
translate的百分比永远参照元素自身尺寸,这是居中技巧和双开门位移的共同前提。- 多重转换的结果依赖书写顺序:位移在前、旋转在后,才能保证位移方向可控。
transform-origin决定旋转和缩放的作用中心,时钟指针、轮播图两侧缩放都靠它定位。- 渐变属于
background-image而非颜色,方向关键字、色标位置都可省略,缺省时按默认方向铺满。 - 3D 效果必须同时满足两个条件:祖先有
perspective(近大远小),直接父级有transform-style: preserve-3d(保留子元素的三维空间),缺一不可。 perspective值越小变化越剧烈,越大越平缓;Z 轴位移只能用 px,因为盒子没有厚度可作百分比参照。- 3D 旋转的正负方向用左手法则判断:大拇指指向轴的正方向,四指弯曲方向即正角度方向。
- 3D 转换在实际业务中极少手写,掌握到"能看懂、能改、能排查失效原因"即可,不必追求独立默写立方体。