Skip to content

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

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

学习目标 ​

  • 能够说明字体图标的适用场景,独立引入 iconfont 的 CSS 文件并通过类名在页面中显示图标,且能调整图标大小与颜色。
  • 能够处理字体图标样式不生效的权重问题,并通过提高选择器权重或使用 !important 验证修复效果。
  • 能够在图标库缺少所需图标时,向 UI 获取 SVG 文件,完成 iconfont 上传、去除颜色提交审核、加入购物车并下载使用的流程。
  • 能够写出 transform: translate() 的完整语法,区分单值、translateX()、translateY()、正负值及百分比含义,并实现元素悬浮位移效果。
  • 能够使用绝对定位配合 transform: translate(-50%, -50%) 实现子盒子相对父盒子的水平垂直居中。
  • 能够完成“开门”案例布局,使用 hover 配合左右位移实现开门动画,并用 transform: rotate() 与 deg 实现顺/逆时针旋转及过渡效果。

知识点 ​

平面转换是什么 ​

作用:为元素添加动态效果,一般与过渡配合使用。概念:改变盒子在平面内的形态(位移、旋转、缩放、倾斜)。

平面转换示意图

平面转换也叫 2D 转换,属性是 transform。为什么需要:页面里常见的鼠标悬停位移、图片放大、按钮旋转,都靠它完成。怎么想:先记住它改变的是元素在平面 X/Y 轴上的“形态”,X 正方向向右,Y 正方向向下。怎么做:写 transform: 具体转换函数(...)。易错点:转换函数写错、角度和像素单位混用;多个转换写在一起时顺序会影响结果。

平移 ​

css
transform: translate(X轴移动距离, Y轴移动距离);

为什么需要:让盒子在平面上移动,做开门、悬浮位移等效果。怎么想:两个值分别控制 X、Y;正负均可,百分比参照盒子自身尺寸计算。怎么做:translate(100px,100px) 向右下移动;只写一个值表示沿 X 轴移动;单独设置用 translateX() 或 translateY()。易错点:百分比不是参照父级,而是自身宽高;translateX/Y 的 X、Y 要大写;想看到缓慢移动要配 transition。转写稿里调试过:100% 相当于“自己多宽就走多远”。

定位居中 ​

margin居中示意图

平移居中示意图

为什么需要:子盒子相对父盒子上下左右居中很常见。怎么想:旧方案是绝对定位 top:50%; left:50% 先到父级中心点,但此时子盒子左上角在中心,还要拉回自身一半。怎么做:旧方案用 margin-left/margin-top 负的自身一半,需要计算;新方案用 transform: translate(-50%,-50%),不用管盒子具体宽高。易错点:margin 的百分比参照父级宽度,不等于自身一半;转写稿中试过负 margin 百分比不理想,最后用 translate(-50%,-50%) 解决。

案例-双开门 ​

双开门效果图

为什么需要:综合练习位移、背景定位、过渡和 hover。怎么想:父级放整张背景图并 overflow:hidden;左右两个子盒子各占 50%,右盒子用 background-position:right 0 取精灵图右侧;鼠标悬停父级时,左门向左移 -100%,右门向右移 100%。

html
<div class="father">
    <div class="left"></div>
    <div class="right"></div>
</div>
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%);
}

易错点:过渡加在左右门上,不是加在 hover 里;overflow:hidden 用来裁掉移出去的部分;左右移动方向别写反。

旋转 ​

css
transform: rotate(旋转角度);

为什么需要:做时钟指针、按钮转动等效果。怎么想:角度单位是 deg;正值顺时针,负值逆时针。怎么做:rotate(90deg)。易错点:转 360deg 看起来像没转,因为一圈回到原位;转写稿中加 transition 并观察角或文字才明显。

转换原点 ​

默认情况下,转换原点是盒子中心点

css
transform-origin: 水平原点位置 垂直原点位置;

为什么需要:时钟指针要绕底部转,而不是绕中心转。怎么想:先确定绕哪个点旋转。怎么做:取值可用方位名词、像素、百分比,如 center bottom。易错点:原点设置和旋转要配合;时钟指针常用 transform-origin:center bottom。

时钟效果图

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;
}

多重转换 ​

多重转换技巧:先平移再旋转。

css
transform: translate() rotate();

为什么需要:既要移动又要旋转时,顺序会改变坐标轴。怎么想:旋转会改变元素坐标轴向;先写旋转,后面的转换会按旋转后的轴向计算。怎么做:一般先 translate() 再 rotate()。易错点:顺序写反,位移方向会“歪”。

缩放 ​

css
transform: scale(缩放倍数);
transform: scale(X轴缩放倍数, Y轴缩放倍数);

为什么需要:做图片悬停放大、播放按钮弹出。怎么想:一个值表示 X/Y 等比例缩放;大于 1 放大,小于 1 缩小。怎么做:scale(1.2)。易错点:scale() 不写单位;播放特效里常和 opacity、transition 配合。

播放特效图

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;
}

易错点:伪元素定位居中仍用 translate(-50%,-50%);初始 scale(5) 配合 opacity:0,悬停回到 scale(1)。

倾斜 ​

css
transform: skew();

为什么需要:做倾斜卡片等变形效果。怎么想:取值是角度度数 deg。怎么做:如 skew(10deg)。易错点:单位写 deg,不要写 px。

渐变在移动 Web 基础中的位置 ​

本节属于移动 Web 布局前的基础知识。转写稿里把这一阶段概括为四大块:字体图标、平面转换、渐变、3D 空间转换,并说明重点是平面转换。这里要纠正几个同音字:不是“字体浮标”,而是“字体图标”;不是“平面转化”,而是“平面转换”;不是“3D 空间转化”,而是“3D 空间转换”。渐变虽然单词较长,但明确说不推荐死记,使用时能查出来、跟着会写即可,它本质上仍是 CSS 样式。

为什么需要:页面里经常要给盒子加背景层次,纯色背景有时太生硬,渐变可以让多个颜色平滑过渡。
怎么想:先判断是线性渐变还是径向渐变,再确定方向、颜色和颜色终点位置。
怎么做:用 background-image 设置渐变,而不是把它当成普通背景色。
易错点:不要把 linear-gradient() 直接写给 background-color;颜色之间用英文逗号分隔;透明色可用 transparent 或 rgba()。

渐变是多个颜色逐渐变化的效果,一般用于设置盒子背景。分类如下:

  • 线性渐变

线性渐变示意图

  • 径向渐变

径向渐变示意图

线性渐变 ​

为什么需要:线性渐变适合做从一个方向过渡到另一个方向的背景,例如遮罩、 banner 底部压暗、卡片背景等。
怎么想:先想“往哪个方向渐变”,再想“有哪些颜色,每个颜色停在哪里”。方向和终点位置都是可选项,不写时浏览器会按默认规则处理。
怎么做:使用如下语法:

css
background-image: linear-gradient(
  渐变方向,
  颜色1 终点位置,
  颜色2 终点位置,
  ......
);

取值:

  • 渐变方向:可选
    • to 方位名词
    • 角度度数
  • 终点位置:可选
    • 百分比

易错点:方向写在第一个参数位置;颜色和终点位置之间用空格;多个颜色之间用逗号;如果只写颜色不写终点位置,颜色会按浏览器默认分布。

案例-产品展示 ​

为什么需要:产品图上方直接放白色文字可能看不清,需要在图片底部加一层由透明到黑色的渐变遮罩,鼠标悬停时再显示。
怎么想:先搭结构:图片、标题、遮罩三层;遮罩绝对定位覆盖整个盒子;默认 opacity: 0 隐藏,hover 时变为 1;过渡写在 .mask 上。
怎么做:笔记中的结构和样式如下。

产品展示案例效果图

  • 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 用了绝对定位,实际使用时要注意父级定位上下文;transparent 表示透明,rgba(0,0,0,0.5) 表示半透明黑色;过渡加在 .mask 上,而不是只写在 :hover 里;悬停选择器要写清楚父子关系。

径向渐变 ​

为什么需要:径向渐变从一个圆心向外扩散,适合做光晕、圆形高光、中心发散的背景效果。
怎么想:先确定圆心和半径,再确定颜色顺序。半径可以写一条,也可以写两条;写两条时为椭圆。圆心位置可用像素、百分比或方位名词。
怎么做:使用如下语法:

css
background-image: radial-gradient(
  半径 at 圆心位置,
  颜色1 终点位置,
  颜色2 终点位置,
  ......
);

取值:

  • 半径可以是2条,则为椭圆
  • 圆心位置取值:像素单位数值 / 百分比 / 方位名词

易错点:at 用来连接半径和圆心位置;半径写两条时注意顺序;圆心位置不要和颜色终点位置混淆;仍然要写在 background-image 中。

小结与练习建议 ​

本节转写稿没有展开渐变的逐步调试,主要提醒是:渐变单词长,不要求死记,忘了就查语法,能跟着写出来即可。练习时先写线性渐变,再做产品展示遮罩,最后试径向渐变。检查重点是:渐变是否写在 background-image、颜色逗号是否为英文、遮罩定位和 opacity 过渡是否生效。

课件图示 ​

课件第3页: 作用:为元素添加动态效果,一般与过渡配合使用  概念:改变盒子在平面内的形

课件第4页: 属性  取值  像素单位数值  百分比(参照盒子自身尺寸计算结果) 

课件第9页: 属性  角度单位是deg  技巧  取值正负均可  取值为正,顺时针

课件第10页: 默认情况下,转换原点是盒子中心点  属性  取值  方位名词(left

课件第12页: 多重转换技巧:先平移再旋转 平面转换– 多重转换 transform: tr

课件第13页:多重转换原理:以第一种转换方式坐标轴为准转换形态 旋转会改变网页元素的坐标轴

课件第14页: 思考: 改变元素的width或height属性能实现吗?  属性  技巧

课件第16页: 属性  取值  角度度数deg 平面转换– 倾斜 transform:

代码示例 ​

示例一:平移语法 + 定位居中 ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>平移与定位居中</title>
  <style>
    * { margin: 0; padding: 0; }

    /* ---------- 1. 平移基本语法 ---------- */
    .box {
      width: 200px;
      height: 200px;
      background-color: pink;
      margin: 100px auto;
      transition: all .5s;          /* 过渡写在基础盒子上 */
    }
    .box:hover {
      /* transform: translate(100px, 100px);  X 正右、Y 正下 */
      /* transform: translate(-100px, 100px); 负值往左 */
      /* transform: translate(100%);          百分比参照盒子自身宽度 */
      /* transform: translateX(100px);        只沿 X 轴,X 必须大写 */
      transform: translateY(100px);           /* 只沿 Y 轴 */
    }

    /* ---------- 2. 定位居中 ---------- */
    .father {
      position: relative;
      width: 600px;
      height: 400px;
      border: 1px solid #999;
      margin: 0 auto;
    }
    .son {
      position: absolute;
      left: 50%;
      top: 50%;
      width: 188px;                 /* 故意用不整的数字 */
      height: 166px;
      background-color: #ccc;
      /* 旧方案要自己算一半:margin-left: -94px; margin-top: -83px; */
      transform: translate(-50%, -50%);
    }
  </style>
</head>
<body>
  <div class="box"></div>

  <div class="father">
    <div class="son"></div>
  </div>
</body>
</html>

关键行与易错点

  • transform: translate(X, Y) 的两个值分别对应 X 轴、Y 轴;X 正方向向右、Y 正方向向下,正负值都可写。
  • 只写一个值 translate(100px) 时,只表示沿 X 轴 移动,Y 轴不动;要单独控制 Y 轴用 translateY(),注意 X / Y 必须大写,小写不生效。
  • 百分比参照 盒子自身尺寸:translate(100%) 就是“自己多宽就走多远”,和父级宽度无关。
  • 居中方案:left: 50%; top: 50% 只是把子盒子的左上角移到父级中心点,所以还要 translate(-50%, -50%) 把自身一半拉回来;这样不用管宽高是多少,彻底免去旧方案 margin-left: -94px 那种手算。
  • transition 必须写在基础状态 .box 上,写在 :hover 里只能“进去有过渡、出来没过渡”。

示例二:双开门(精灵图 + 平移) ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>双开门</title>
  <style>
    * { margin: 0; padding: 0; }   /* 消除 body 默认 8px 外边距 */

    /* 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%);
    }
  </style>
</head>
<body>
  <div class="father">
    <div class="left"></div>
    <div class="right"></div>
  </div>
</body>
</html>

关键行与易错点

  • 两扇门共用一张图 fm.jpg,右门用 background-position: right 0 把图“右半边”显示出来,这就是笔记里说的精灵图思路。
  • translate(-100%) 的参照是门自身宽度(父级的一半),所以正好把门推出父盒子宽度的一半,左右对称。
  • overflow: hidden 不能漏:门被推出去会撑出横向滚动条。
  • * { margin: 0; padding: 0; } 同样不能漏,body 默认 8px 外边距会让 1366px 的盒子超出屏幕。
  • transition 写在 .left / .right 上而不是 :hover 里,这样鼠标移出时门也会缓缓关上。

示例三:缩放播放特效 + 渐变遮罩 ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>播放特效与渐变遮罩</title>
  <style>
    * { margin: 0; padding: 0; }
    body { padding: 50px; }
    ul { list-style: none; }
    .box { display: flex; gap: 20px; }
    .box li { overflow: hidden; }

    .pic { position: relative; width: 300px; height: 200px; }
    .pic img { width: 100%; height: 100%; display: block; object-fit: cover; }

    /* 1. 摆放播放按钮:图片区域的中间 */
    .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);   /* 换成你自己的图标 */
      background-size: cover;
      transform: translate(-50%, -50%) scale(5);  /* 先平移,再放大 */
      opacity: 0;
      transition: all .5s;
    }

    /* 2. hover 效果:大按钮看不见 → 小按钮看得见 */
    .box li:hover .pic::after {
      transform: translate(-50%, -50%) scale(1);
      opacity: 1;
    }

    /* 3. 产品展示的渐变遮罩 */
    .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 li:hover .mask { opacity: 1; }
  </style>
</head>
<body>
  <ul class="box">
    <li>
      <div class="pic">
        <img src="./images/product.jpeg" alt="" />
        <div class="mask"></div>
      </div>
    </li>
  </ul>
</body>
</html>

关键行与易错点

  • 多重转换的顺序极其关键:translate(-50%, -50%) scale(5) 是先平移再缩放,位移距离按原始尺寸计算;如果写成 scale(5) translate(-50%, -50%),坐标轴已被放大 5 倍,位移也跟着放大,按钮会跑偏。笔记的结论就是“先平移再旋转/缩放”。
  • scale() 只写一个值表示 X、Y 等比缩放;大于 1 放大,小于 1 缩小,不需要写单位。
  • 显隐用 opacity 而不是 display: none,因为 opacity 可以参与过渡,也不会改变布局。
  • 渐变必须写在 background-image: linear-gradient(...) 上,写成 background-color 是无效的。
  • linear-gradient 默认方向从上到下,第一个色 transparent 让图片上方透明、下方变暗;颜色终点位置可选用百分比控制。
  • 定位居中同样用 left/top: 50% + translate(-50%, -50%),比 margin-left: -29px 这种硬算一半更省事。

常见错误 ​

  • 现象:绝对定位 top:50%; left:50% 后再写 translate(50%,50%),盒子偏到右下。原因:translate 百分比参照元素自身尺寸,方向写反。修法:改为 translate(-50%,-50%)。
  • 现象:双开门只有鼠标移到单扇门上才动,左右不同步。原因:hover 写在了子元素上。修法:用父级控制子元素,如 .father:hover .left、.father:hover .right。
  • 现象:鼠标移入有过渡,移出生硬跳回。原因:transition 写在 :hover 状态里。修法:把 transition 放在元素基础状态。
  • 现象:transform: rotate(...) translate(...) 后位移方向歪掉。原因:旋转改变坐标轴,多重转换顺序影响结果。修法:按需求先写 translate() 再写 rotate()。
  • 现象:时钟指针绕自身中心转,不绕底部。原因:未设置转换原点。修法:给指针设置 transform-origin: center bottom。
  • 现象:遮罩写 background-color: linear-gradient(...) 不显示渐变。原因:linear-gradient() 是背景图值,不是颜色值。修法:改用 background-image 或 background。

练习 ​

  1. 用绝对定位实现子盒子在父盒子中上下左右居中,要求不计算子盒子宽高,并说明为什么用 -50%。
  2. 完成双开门案例:鼠标悬停父盒子时,左门向左移出、右门向右移出,移入移出都要有过渡。
  3. 完成时钟指针布局:时、分、秒针分别设置旋转角度,并保证都绕指针底部旋转。
  4. 写一个“小车先平移再旋转”的 transform 组合,并交换顺序观察差异,记录哪一版符合预期。
  5. 给产品图添加底部渐变遮罩:默认透明,悬停显示从透明到半透明黑的线性渐变。

原视频对照 ​

#视频时长
1今日重点02:15
2字体图标15:09
3案例-字体图标03:14
4上传图标08:05
5位移-1-基本语法15:43
6位移-2-居中07:28
7位移-3-开门案例13:57
8旋转-1-基本06:36

小结 ​

  • 居中场景优先考虑 translate(-50%,-50%),避免依赖固定宽高计算。
  • hover 动画的控制选择器要写清作用域,父级触发、子级变化更稳定。
  • transition 应放在基础状态,保证进入和离开都有过渡。
  • 多重转换顺序不是随意排列,先平移再旋转通常更符合预期。
  • 旋转类案例先确认转换原点,再调角度和过渡时间。
  • 渐变用于背景图属性,不要误写成背景颜色属性。
  • 调试时先看选择器是否命中,再看属性值是否生效,最后看状态切换是否成对。