Skip to content

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

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

学习目标 ​

  • 能说明 transform-origin 的默认旋转原点,并使用方位名词、像素值或百分比设置指定原点,完成绕指定点旋转的效果。
  • 能按正确顺序书写复合变换(先 translate 后 rotate),解释书写顺序对位移方向的影响,并实现元素边位移边旋转的效果。
  • 能使用 scale 设置单值或双值缩放,正确区分放大与缩小,说明缩放对子元素和文字的影响,并完成 hover 缩放交互案例。
  • 能使用 linear-gradient() 创建多色渐变,设置渐变方向或角度,使用 transparent、rgba() 控制透明度,并说明渐变背景的过渡限制。
  • 能独立搭建综合案例的底图、遮罩层和底部信息层,使用定位、overflow: hidden、opacity 等完成初始化状态与 hover 交互,并通过公共过渡类统一过渡效果。

知识点 ​

渐变是什么 ​

渐变是多个颜色逐渐变化的效果,一般用于设置盒子背景。它和普通纯色背景最大的区别是:纯色用 background-color,渐变要用 background-image,因为浏览器把渐变当成一张“背景图片”来绘制。

线性渐变示意图

径向渐变示意图

为什么需要:纯色背景容易单调;在图片上压文字时,也需要一层从透明到深色的遮罩,让文字更清楚。
怎么想:先判断颜色是“沿一条线变化”还是“从中心向外扩散”,前者用线性渐变,后者用径向渐变。
怎么做:记住核心属性是 background-image,里面写 linear-gradient() 或 radial-gradient()。
易错点:不要写成 background-color: linear-gradient(...);渐变里的颜色可以有多个,参数之间用逗号分隔。

线性渐变 ​

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

取值:

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

为什么需要:线性渐变适合做从上到下、从左到右、斜向的过渡背景。
怎么想:先想“颜色朝哪个方向变”,再想“有哪几个颜色、每个颜色停在什么位置”。
怎么做:先写两个颜色看默认效果。转写稿里先写 red、blue,观察到默认是红在上、蓝在下;再在第一个位置加 to right,变成从左到右;又试 0deg、90deg 观察角度。调试后可知:默认方向可理解为从上到下,90deg 是从左到右。
易错点:方向和颜色之间是逗号;to right 是一个整体;角度写法是 90deg,不要漏单位。颜色也可以写十六进制、rgba()、transparent。

案例-产品展示 ​

产品展示案例效果

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

为什么需要:图片上的标题如果直接放,遇到浅色图片会看不清,所以需要一层“透明到半黑”的遮罩。
怎么想:遮罩要盖住整张图,所以用定位;默认不显示,用 opacity: 0;鼠标移入再显示。渐变从 transparent 到 rgba(0,0,0,0.5),上方透明、下方变暗。
怎么做:父盒子 .box 作为定位参照,.mask 绝对定位铺满;给 .mask 写线性渐变和透明度过渡;.box:hover .mask 把透明度改为 1。
易错点:.mask 要铺满父盒子;渐变本身通常不能直接做 transition,这里过渡的是 opacity;rgba 第四个值才是透明度。

径向渐变 ​

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

取值:

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

为什么需要:径向渐变适合做中心高光、光晕、圆形按钮的立体感。
怎么想:先确定圆心在哪里,再确定半径多大,最后写颜色从中心到外部的变化。
怎么做:例如把圆心放中间,可写 radial-gradient(circle at center, #fff, #000);若要椭圆,可给两条半径。
易错点:半径 at 圆心位置 是一个整体参数,不要和颜色顺序写反;颜色后的位置是可选值,不写也能形成均匀过渡。

易错点小结 ​

渐变是“背景图片”,不是背景色;线性渐变默认从上到下,方向可写 to 方位名词 或角度;径向渐变要关注“半径 + 圆心”;产品遮罩案例的关键是定位铺满、渐变压暗、opacity 过渡。遇到记不住的方向写法,可以像转写稿里那样先写两个颜色,再查资料、改参数、刷新观察,这是最稳妥的调试方式。

案例总览 ​

综合案例效果图

本节把导航频道、渐变按钮、轮播图、猜你喜欢等效果串成一个综合案例。转写稿反复强调的分析方法是:先看“鼠标移入谁”,再问“谁怎么了”,然后分别用盒子承接变化。为什么需要:综合案例容易一上来就写样式,导致层级和状态混乱。怎么想:先拆变化,再定盒子,最后写 hover 状态。怎么做:每个模块先写常态,再写 hover,过渡写在常态或公共类上。易错点:hover 里只写变化,不要把过渡也临时塞进去,否则移出时没有过渡。

导航频道:箭头旋转与频道弹层 ​

为什么需要:导航悬停时要给用户“可展开”的反馈,箭头和频道列表要同步变化。怎么想:箭头用 rotate 旋转;频道列表用绝对定位放在导航下方,初始上移隐藏,hover 回到 0。怎么做:箭头 hover 旋转 -180deg;频道列表初始 translateY(-120px),hover 改为 translateY(0),过渡写在常态。易错点:z-index:-2 与定位要配合,left:50% 后要用负 margin 拉回;过渡不要只写在 hover 中。

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

转写稿补充:旋转默认绕盒子中心点,若要绕其他点,用 transform-origin,如 0 0 是左上角,方位名词也可控制;它要在旋转前设置好。易错点:transform-origin 两个值用空格,不是逗号。

渐变按钮:线性渐变与径向渐变 ​

为什么需要:纯色按钮层次弱,渐变能做出高光和立体感。怎么想:搜索、登录按钮用线性渐变,从左到右叠加半透明白;客户端按钮用径向渐变做局部高光。怎么做:渐变写在 background-image,不是 background-color。易错点:颜色值、方向、圆角要配套;径向渐变要写清大小和位置。

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

转写稿调试:渐变默认从上到下;要改方向可在第一个位置写 to right 或角度,0deg、90deg 要刷新观察。易错点:渐变按背景图片处理,不能像纯色那样直接过渡。

轮播图:左右图片的定位与缩放 ​

为什么需要:轮播两侧图片要缩小并靠边,形成层次。怎么想:左侧图向左移并缩小,右侧图向右移并缩小,缩放原点分别靠左、靠右。怎么做:用 translate 加 scale,配合 transform-origin。易错点:左右方向写反、缩放原点不设会导致图片位置跑偏。

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

转写稿补充:复合变换中移动要写在旋转前,如 translateX(800px) rotate(720deg);若 rotate 在前,X 轴方向会随旋转改变,轨迹就不对。易错点:不要凭“说法一样”反写顺序。

猜你喜欢:遮罩播放按钮与图片缩放 ​

为什么需要:hover 时要有播放提示和图片放大反馈。怎么想:用 ::after 做遮罩和播放图标,默认透明,hover 显示;图片 hover 放大。怎么做:遮罩用绝对定位铺满,背景图居中;opacity 和 background-size 过渡;图片用 scale(1.1)。易错点:父级要定位,否则 ::after 不相对父级;缩放会连子元素和文字一起缩放,注意溢出隐藏。

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

综合案例交互:三盒子与公共过渡类 ​

为什么需要:一个卡片 hover 时同时发生底图放大、渐变遮罩出现、底部信息上移。怎么想:用三个子盒子分别承接三个变化,变化互不干扰。怎么做:底图 hover 时 scale;遮罩层用线性渐变从透明到 rgba(0,0,0,.8);底部信息初始 bottom:-80px,hover 回 0;多个元素需要过渡时抽公共类名,统一写 transition。易错点:渐变遮罩是背景图片,过渡不了;过渡类名别丢,否则效果生硬;底部信息上移可用定位,不必强行只用手学位移。

课件图示 ​

课件第17页: 渐变是多个颜色逐渐变化的效果,一般用于设置盒子背景  分类  线性渐变

课件第20页: 作用:给按钮添加高光效果  属性  取值  半径可以是2条,则为椭圆

代码示例 ​

示例一:线性渐变基础与方向控制 ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>线性渐变</title>
  <style>
    .box {
      width: 300px;
      height: 150px;
      border: 1px solid #000;
      margin-bottom: 20px;
      /* 不写方向:默认从上到下,等价于 180deg */
      background-image: linear-gradient(red, blue);
    }

    .box2 {
      width: 300px;
      height: 150px;
      border: 1px solid #000;
      margin-bottom: 20px;
      /* 方向:to + 方位名词 */
      background-image: linear-gradient(to right, red, blue);
    }

    .box3 {
      width: 300px;
      height: 150px;
      border: 1px solid #000;
      margin-bottom: 20px;
      /* 方向:角度度数,0deg 从下往上,90deg 从左往右 */
      background-image: linear-gradient(45deg, red, blue);
    }

    .box4 {
      width: 300px;
      height: 150px;
      border: 1px solid #000;
      /* 多颜色 + 终点位置(百分比) */
      background-image: linear-gradient(
        to right,
        red 0%,
        yellow 30%,
        blue 100%
      );
    }
  </style>
</head>
<body>
  <div class="box"></div>
  <div class="box2"></div>
  <div class="box3"></div>
  <div class="box4"></div>
</body>
</html>

要点解释 / 易错点

  • 渐变色写在 background-image 里,不是 background-color,写成 background-color: linear-gradient(...) 无效,这是最常见的错误。
  • 语法:linear-gradient(渐变方向, 颜色1 终点位置, 颜色2 终点位置, ...),颜色之间用逗号分隔。
  • 渐变方向可省略,省略时默认从上到下(即 180deg)。
  • 方向可写 to 方位名词(to right / to top left 等),也可写角度 deg;0deg 是从下往上,90deg 是从左往右,负角度表示反方向。
  • 颜色可以写很多个,终点位置(百分比)是可选的,不写则平均分配。

示例二:产品展示(渐变遮罩 + hover 淡入) ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>产品展示</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    /* 父盒子:子绝父相 */
    .box {
      position: relative;
      width: 400px;
      margin: 50px auto;
      overflow: hidden;
    }

    .box img {
      display: block;
      width: 100%;
    }

    /* 标题压在图片底部(补充的布局样式) */
    .box .title {
      position: absolute;
      left: 0;
      bottom: 0;
      z-index: 1;
      width: 100%;
      padding: 20px 15px 15px;
      color: #fff;
      font-size: 16px;
    }

    /* 渐变遮罩:核心代码 */
    .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 0.5s;
    }

    .box:hover .mask {
      opacity: 1;
    }
  </style>
</head>
<body>
  <div class="box">
    <img src="./images/product.jpeg" alt="" />
    <div class="title">OceanStor Pacific 海量存储斩获2021 Interop金奖</div>
    <div class="mask"></div>
  </div>
</body>
</html>

要点解释 / 易错点

  • 遮罩 .mask 要盖满图片,必须 position: absolute + left: 0; top: 0; width: 100%; height: 100%,所以父盒子 .box 必须 position: relative(子绝父相)。
  • 渐变第一个颜色用 transparent(完全透明),第二个用 rgba(0,0,0,0.5)(半透明黑),这样才是“下深上透”的自然遮罩。
  • 初始 opacity: 0,.box:hover .mask 时 opacity: 1,配合 transition: all .5s 实现淡入。
  • 图片如果是 img 标签,记得 display: block,否则图片底部会多出几像素空白,遮罩对不齐。
  • 文字想压在遮罩上面,需要给 .title 加 z-index(或调整 DOM 顺序),否则会被遮罩盖住。

示例三:径向渐变按钮 ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>径向渐变</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      padding: 50px;
      background-color: #f5f5f5;
    }

    .dl-btn {
      width: 68px;
      height: 34px;
      line-height: 34px;
      color: #fff;
      text-align: center;
      border-radius: 4px;
      /* 底色,让径向渐变有叠加的基色 */
      background-color: #ff7251;
      /* 径向渐变:半径 at 圆心位置, 颜色1, 颜色2 */
      background-image: radial-gradient(
        50px at 10px 10px,
        rgba(255, 255, 255, 0.5),
        transparent
      );
    }

    /* 椭圆径向渐变:半径写两个值 */
    .dl-btn2 {
      width: 200px;
      height: 100px;
      margin-top: 30px;
      line-height: 100px;
      color: #fff;
      text-align: center;
      border-radius: 4px;
      background-color: #ff7251;
      background-image: radial-gradient(
        80px 40px at center,
        rgba(255, 255, 255, 0.6),
        transparent
      );
    }
  </style>
</head>
<body>
  <div class="dl-btn">下载</div>
  <div class="dl-btn2">椭圆径向渐变</div>
</body>
</html>

要点解释 / 易错点

  • 语法:radial-gradient(半径 at 圆心位置, 颜色1 终点位置, 颜色2 终点位置, ...),at 前面是半径,at 后面是圆心。
  • 半径写两个值(如 80px 40px)就变成椭圆;写一个值则是正圆。
  • 圆心位置可写像素值、百分比或方位名词(center、left top 等),如 at 10px 10px 表示光晕在左上角。
  • 径向渐变同样写在 background-image 里,和 background-color 是叠加关系——先写 background-color 打底,再叠径向渐变,才能看到“高光”效果。
  • 渐变本身是图片,不能像纯色那样做 background-color 过渡,颜色突变时不会有平滑过渡,这一点要心里有数。

常见错误 ​

  1. 现象:写了渐变但盒子仍是纯色。
    原因:把 linear-gradient() / radial-gradient() 写在 background-color 里,或只写了颜色值。
    修法:改为 background-image 或 background,把渐变函数作为背景图使用。

  2. 现象:渐变方向与预期相反,斜向渐变角度调不准。
    原因:默认方向未验证,to 方位名词 与角度混用后没有实测校准。
    修法:先明确首参;需要斜向时用 to bottom right 一类写法或角度,并用 0°、90° 实测确认方向。

  3. 现象:transform-origin 整条声明失效,旋转原点没变化。
    原因:两个位置值用了逗号分隔,或把原点写在 :hover 触发规则里。
    修法:用空格分隔水平、垂直位置;原点写在触发变换前的基态规则中。

  4. 现象:复合变换后移动路径“拐弯”,不是预期的直线加旋转。
    原因:rotate() 写在 translate() 前面,后续位移轴受旋转影响。
    修法:按需求把 translate() 放在 rotate() 前;调试时拆成单项变换分别验证。

  5. 现象:scale() 放大后溢出可见,或出现不该显示的大三角、边缘。
    原因:只写了缩放,没有处理父级溢出和元素初始透明度。
    修法:父级加 overflow: hidden;需要隐藏的元素基态加 opacity: 0,交互时恢复。

  6. 现象:hover 退出时很生硬,或渐变遮罩淡入淡出无效。
    原因:transition 只写在 :hover 内;对渐变背景图本身做过渡。
    修法:transition 放基态或公共类;渐变遮罩用 opacity 做过渡,不要直接过渡渐变背景。

  7. 现象:径向渐变按钮高光位置不对。
    原因:半径、at、圆心位置的顺序或单位写混。
    修法:按 半径 at 圆心位置 书写;先固定圆心,再调半径和颜色终点。

练习 ​

  1. 改错题:下面两条声明各有一处问题,请指出并改正。

    css
    .btn { background-color: linear-gradient(to right, rgba(255,255,255,.3), #f86442); }
    .btn:hover { transition: all .3s; }
  2. 产品图遮罩:实现图片容器 hover 时出现从 transparent 到 rgba(0,0,0,.5) 的线性渐变遮罩,遮罩淡入,图片轻微放大;要求溢出隐藏。写出关键选择器和声明。

  3. 轮胎复合动画:hover 时元素向右移动 800px 并旋转 720deg。写出 transform 声明,并说明交换 translate 与 rotate 顺序后会出现什么现象。

  4. 秒针旋转:一个细长条 hover 时旋转,要求以“底部中心”为原点;再改成“左上角”为原点。分别写出 transform-origin 与 transform。

  5. 播放按钮交互:父盒固定尺寸,图标初始 scale(5) 且 opacity: 0,hover 父盒时图标恢复 scale(1)、opacity: 1,要求有过渡且放大时不溢出。列出 HTML 层级思路和关键 CSS。

原视频对照 ​

#视频时长
1旋转-2-原点设置了解07:27
2复合属性07:22
3缩放-1-基本05:43
4缩放-2-缩放案例11:32
5上午小结03:53
6渐变13:40
7综合案例-1-搭建16:12
8综合案例-2-交互效果06:15

小结 ​

  1. 渐变应作为背景图处理,不要误写成普通背景色。
  2. 渐变方向、角度和圆心位置都要以浏览器实际效果为准调试。
  3. 复合变换的顺序会改变最终运动轨迹,移动与旋转要按目标顺序书写。
  4. transform-origin 要在变换触发前设置,且两个位置值用空格分隔。
  5. scale() 会影响元素自身及其文字、子元素,需同时考虑溢出和初始透明。
  6. 过渡应写在基态或公共类上,避免只写在 :hover 导致退出生硬。
  7. 渐变遮罩的显隐优先用 opacity 过渡,不要直接过渡渐变背景。
  8. 综合案例先按“鼠标移入谁,谁怎么了”拆成多个子盒子,再分别承接变化。