← 课程 目录 CSS 课堂演示 · 第 9 章 变换·过渡·动画

CH 09 · 对应教材单元五

变换 · 过渡 · 动画

让页面动起来的三种手段:transform 搬移旋转缩放、transition 给状态切换加缓冲、 @keyframes 让动画自己播。把鼠标悬到下面每个元素上试试。

9.1transform 三板斧:translate / rotate / scale

变换不挤占文档流——悬停看效果:位移、旋转、缩放可以叠加写。

hover 上移
hover 旋转
hover 放大
三合一
.tf:hover { transform: translateY(-8px); }
.tf-rot:hover { transform: rotate(8deg); }
.tf-sca:hover { transform: scale(1.15); }

/* 叠加:空格连写,注意顺序影响观感 */
.tf-all:hover {
  transform: translateY(-6px)
             rotate(-3deg)
             scale(1.05);
}

/* translateX/Y 用百分比也行:
   translate(-50%,-50%) = 居中绝招 */

transform 不触发重排,性能远好于 top/left 位移;「绝对定位居中」用 left:50% + translate(-50%) 组合拳。

9.2transition 四要素对比:有没有过渡,手感差一个时代

属性 + 时长 + 缓动 + 延迟。悬停两个按钮:无过渡的「跳变」,有过渡的「丝滑」。

/* transition: 属性 时长 缓动 延迟 */
.tr-btn {
  transition: all .35s ease;
}
.tr-btn:hover {
  background: #8C3A22;
  transform: translateY(-3px);
  box-shadow: 0 8px 16px rgba(176,74,44,.3);
}

/* 只过渡颜色,其余瞬变 */
.tr-soft { transition: background .6s ease; }

/* 缓动家族:
   linear 匀速 / ease 先快后慢 /
   ease-in 慢进 / ease-out 慢出 */

transition 是「状态切换时」才生效——写在哪条规则上都行,但写 :hover 里移出时会瞬变,所以惯例写在基态。

9.3实战:3D 翻牌卡片

透视 + 双面卡片 + rotateY(180deg)——招式全是本章知识点的组合。

把鼠标放上来
背面:transform-style
+ backface-visibility
/* 1. 外层给「透视距离」 */
.card-flip { perspective: 600px; }

/* 2. 内层 3D 空间 + 翻转过渡 */
.cf-inner {
  transform-style: preserve-3d;
  transition: transform .7s;
}
.card-flip:hover .cf-inner {
  transform: rotateY(180deg);
}

/* 3. 两张面:背面朝外时隐藏 */
.cf-face { backface-visibility: hidden; }
.cf-back { transform: rotateY(180deg); }

缺一不可:没有 perspective 没有立体感,没有 backface-visibility 会「透出正面的字」。

9.4@keyframes 关键帧动画:不用悬停,自己会动

animation 八要素里最常用六个:名字、时长、曲线、延迟、次数、方向。三个真实组件现场播放。

我在滑入滑出
在线脉冲
/* 1. 定义关键帧(命名随意) */
@keyframes bounce {
  0%,100% { transform: translateY(0);    opacity:.6; }
  50%     { transform: translateY(-18px); opacity:1; }
}

/* 2. 挂到元素上 */
.loader span {
  animation: bounce .9s ease-in-out infinite;
}
.loader span:nth-child(2) { animation-delay:.15s; }

@keyframes spin { to { transform: rotate(360deg); } }
.orbit { animation: spin 1.2s linear infinite; }

transition 是「A→B 一次」,keyframes 是「剧本反复播」——加载圈、骨架屏、提示条都靠它。

9.5无限轮播跑马灯(综合案例)

两份内容 + translateX(-50%) 无缝衔接,keyframes 只写一条「从 0 到负一半」。

HTMLCSSJavaScriptFlexGrid
.marquee {
  display: flex;
  width: max-content;   /* 内容有多宽占多宽 */
  animation: marquee 8s linear infinite;
}

/* 平移自身宽度的一半 =
   第二份内容刚好补上第一份的空位 */
@keyframes marquee {
  to { transform: translateX(-50%); }
}

/* 悬停暂停:动画状态可控制 */
.marquee:hover { animation-play-state: paused; }

无缝滚动的关键:内容复制一份 + 位移 -50%。animation-play-state 还能做「hover 暂停」。

9.6动效守则:克制与无障碍

动画是调味料不是主菜;系统开了「减少动态效果」时,要尊重用户的设置。

✅ 该动的:悬停反馈、加载状态、内容入场(一次性)

❌ 别动的:正文文字、整页滚动、常驻闪烁

⏱ 时长:微交互 150~300ms,入场动画 ≤ 600ms

♿ 系统减弱动效时全部关闭(右下角代码)

/* 尊重系统「减少动态」设置:
   开了减弱动效的用户
   看到的所有动画近乎静止 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* 本项目 demo.css 末尾就写了这一段,
   网站根 app.css 同样有 */

只动画 transform 和 opacity 性能最好(GPU 合成层);动画 width/height/margin 会引发重排,慎用。