Skip to content

移动 Web 基础与变换(三) ​

本页对应 移动 Web 基础与变换,共 7 段视频,约 1 小时 15 分。

学习目标 ​

  1. 能使用 transform 完成元素的平面位移、旋转与缩放,并正确设置位移、旋转的复合顺序,通过浏览器验证效果。
  2. 能使用 translate(-50%, -50%) 等位移方案实现盒子在父容器中水平垂直居中。
  3. 能使用 linear-gradient 编写指定方向和多颜色渐变的背景,并应用到综合案例中。
  4. 能解释 perspective 视距的作用,使用 translate3d、translateZ 实现近大远小的空间位移效果。
  5. 能使用 rotateX/rotateY/rotateZ 完成 3D 旋转,并依据左手法则判断正负角度对应的旋转方向。
  6. 能使用 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。

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 是否加在正确的元素上。

原视频对照 ​

#视频时长
13D位移-1-基本11:46
23D位移-2-视距了解07:45
33D旋转-1-基本08:57
43D旋转-2-拓展自定义轴08:12
53D呈现-1-基本14:04
63D呈现-2-导航案例13:42
7今日总结11:23

小结 ​

  1. translate 的百分比永远参照元素自身尺寸,这是居中技巧和双开门位移的共同前提。
  2. 多重转换的结果依赖书写顺序:位移在前、旋转在后,才能保证位移方向可控。
  3. transform-origin 决定旋转和缩放的作用中心,时钟指针、轮播图两侧缩放都靠它定位。
  4. 渐变属于 background-image 而非颜色,方向关键字、色标位置都可省略,缺省时按默认方向铺满。
  5. 3D 效果必须同时满足两个条件:祖先有 perspective(近大远小),直接父级有 transform-style: preserve-3d(保留子元素的三维空间),缺一不可。
  6. perspective 值越小变化越剧烈,越大越平缓;Z 轴位移只能用 px,因为盒子没有厚度可作百分比参照。
  7. 3D 旋转的正负方向用左手法则判断:大拇指指向轴的正方向,四指弯曲方向即正角度方向。
  8. 3D 转换在实际业务中极少手写,掌握到"能看懂、能改、能排查失效原因"即可,不必追求独立默写立方体。