CSS 动画的魔法(以及为什么它比你想象的要简单)

2025-06-10

CSS 动画的魔法(以及为什么它比你想象的要简单)

对于许多开发人员(甚至是前端开发人员)来说,动画有点神秘。

但你无需成为 CSS 高手或专业的 CodePen 艺术家,也能创作出令人印象深刻的视觉效果。你日常看到的大多数动画和效果,其实只需要掌握一些技巧就能完成。

事实上,你只需花6分钟阅读本文,就能学会这些技能!(当然,你还可以再花点时间做练习。)

到最后,你就能轻松区分 atransform和 a transition,甚至弄清楚它们到底keyframes是什么了。你将能够自信地组合自己的动画和效果。

就像这种类似马里奥硬币的动画:(点击一下

动画基础

在 CSS 中,任何具有符合一定范围的值的属性都可以进行动画处理。

字体大小、颜色(因为它们位于色谱中)、屏幕位置,甚至边框半径——所有这些都具有可以在一个范围内表示的值。这与诸如 display 之类的属性形成了对比,后者具有一个封闭的潜在值列表。

display: block中间是什么display: none?现在有一个脑筋急转弯!

因此,我们可以为具有一系列值的任何属性制作动画 - 其中包括该transform属性。

什么是 CSS 变换?

变换不仅仅用于动画 - 它们是一种 CSS 属性,用于操纵事物在屏幕上的呈现方式。

你可以使用它们来执行视觉操作,例如增加对象的大小、旋转、倾斜或移动(或scale, rotate, skew, translate)。你还可以指定仅将变换应用于特定轴。

举两个例子:transform: scale(0.5, 2)是将对象的宽度(X 轴)减半,高度(Y 轴)加倍的简写。同样的语法也可以用来平移对象的位置:transform: translate(5px, 50px)会将其向右移动 5px,向下移动 50px。

现在,假设这幅画是我花了一年时间练习倒立,却几乎毫无进展。如果你能帮rotate我个忙,用 CSS 的话,我可以马上得到它Xdeg,或者Xturn

解决方案:
transform: rotate(90deg)rotate(0.5turn)

如果你想让我倒立,同时又能让我稍微高一点,该怎么办?你可以多个变换组合到同一行。例如transform: rotate(0.5turn) scaleY(2)

3D变换

变换也可以在 3D 环境中操作。要创建马里奥风格的硬币动画,你需要绕其 Y 轴旋转硬币。在这种情况下,2D 旋转对圆形动画没有太大帮助(想象一下将硬币平放并旋转),因此你需要使用rotate3d并告诉浏览器你希望它沿哪个轴移动:

语法transform: rotate3d(x, y, z, degrees)其中 (x,y,z) 分别为 0 到 1 之间的数字,表示轴。要将项目沿 X 轴精确旋转 90 度,可以使用:rotate3d(1, 0, 0, 90)

当你尝试将这枚硬币沿 Y 轴旋转 45 度时会发生什么?如果进行常规的二维旋转会怎样?如果进行90 度的三维旋转呢?

解决方案:transform: rotate3d(0, 1, 0, 45deg)有趣的是,当我们将硬币旋转 90 度时,它就会消失。这在现实生活中是合理的——想象一下将一枚真正的硬币旋转 90 度。如果它没有深度,它就会从视野中消失。在 CSS 中,项目永远不能具有深度(或“挤压”)。我们可以通过使用perspective父框上的属性来创建 3D 空间,然后将 Z 轴位置平移向或远离观察者(transform: translateZ(Xpx)),但这不会创建深度——它只会将对象移近或移远。

过渡:从属性 A 到属性 B

现在,如果你想为一个项目从 A 点移动到 B 点添加动画效果,该怎么办呢?或者是一个颜色变化、旋转过渡、缩放过渡,或者其他许多可动画的 CSS 属性之一?(完整列表请见此处) 。这时,我们就需要用到transitions了。

要定义一个基本的(非关键帧)过渡,您需要告知浏览器过渡起始时刻的样式、过渡完成后的样式以及有关过渡本身的任何其他信息。例如:

示例 1 - 悬停效果

让我们创建当鼠标悬停在阳光上时产生的简单的阳光效果。

语法:要创建转换,您可以使用简写在一行中定义所有属性:

transition: border-radius 2s ease-in 5s;

或者您可以单独定义每个属性,例如:

transition-property: border-radius;
transition-duration: 2s;
transition-timing-function: ease-in;
transition-delay: 5s;

这是我们最初的阳光——把鼠标悬停在上面,你会看到光晕。但阳光看起来可不是那样的!

让我们通过为阳光的 box-shadow 属性添加过渡来创建一个漂亮的渐变阳光效果。

解决方案:transform: box-shadow 2s;聪明的观察者会注意到,我使用了与上面硬币相同的演员;)

示例 2 - 硬币旋转

让我们回到之前的硬币,但现在我想让你添加一个旋转效果。用户点击这枚硬币,它会绕 Y 轴旋转 180 度。为此,你需要在活动状态声明一个旋转变换,并在基础状态声明一个过渡。你可以在这里用最初的硬币练习一下。

并检查您的工作或在此处查看所需的效果:(单击并按住

注意,当活动状态移除时,动画会倒退。这是因为一旦对象不再处于活动状态,变换就会变为隐含的旋转 0。相同的过渡会重新应用,但会回到起始值。

示例 3- 加倍

让我们把两个过渡效果合并起来!要实现这个马里奥风格的硬币动画效果,你可以在一行代码中合并两个过渡效果,例如:

transition: transform 2s, padding 100s

为了使硬币的价值在上升时神奇地出现,请在透明度顶部值上定义一个过渡。(单击并按住硬币即可查看起始效果)

解决方案:现在,如果您希望货币价值缓慢上升、出现,然后像烟雾transition: opacity 2s, top 2s;一样迅速消失在天空中,该怎么办

您需要对动画进行更精细的控制,您可以通过...来实现。

动画+关键帧

当我们想要对动画进行更精细的控制时,可以使用cssanimation属性——无论是通过使用关键帧来描述效果的组成部分,还是通过设置 的其他值。与常规过渡(在对象上定义开始和结束的 CSS)不同,动画只在对象上定义开始的 CSS。之后,动画属性将接管所有 CSS 直到结束。transitionsanimation

Animation与 共享许多属性transition,并且 - 与转换一样 - 您可以用简写或单独的属性来定义它的值。

但是,您必须提供相应的信息keyframe

.myObject {
    animation: fancy-keyframes 5s linear;
}

你可以通过声明一个关键帧来定义关键帧@at-rule,然后使用from整个to序列的百分比,或上述任何变体。例如:

@keyframes fancy-keyframes {
  from {
    top: 0;
    opacity: 0;
  }
  10% {
    top: 10px;
    opacity: 1;
  }
  75% {
    top: 0px;
    margin-top:
  }
  to {
    top: 200px;
    opacity: 0;
  }
}

至此,你应该已经掌握了构建最终烟雾升起动画所需的所有技能!回到之前的 CodePen,用关键帧来实现它,挑战一下自己

这就是我们想要的效果。先别急着看 CSS!(点击并按住即可查看效果)

行业秘密:这里有一个棘手的问题,就是如何在某个点暂停动画。要做到这一点,你只需在稍后的百分比复制一个关键帧即可。:)

当然,这实际上不是抢金币的原理!我们不应该需要按住鼠标才能让动画播放到最后。有一些(非常)hacked CSS 方法可以实现这一点,但说实话,在这种情况下,我会放下我的 CSS 帽子,戴上我的 JavaScript 帽子。合适的工具适合合适的工作。

我们可以使用 React、Vue 或任何框架来实现这一点,但我们需要做的就是添加一个 onClick 类,所以我们不妨只使用原始 JS(还记得吗?)。

我们将创建一个 JavaScript 函数来添加一个类(element.classList.add(myClassName)),然后将其添加到onClick我们的 coin 元素中。此外,我们还会为动画添加一些动画!

现在,不用多说...点击硬币

祝动画制作愉快!


如果您喜欢这篇文章,请查看我在egghead.io上创建的一些课程。

致谢

非常感谢NitzanDeb抽出时间审阅这篇文章并给出宝贵的反馈!也感谢OferDiana在Lemonade Insurance制作出一些令人印象深刻的视觉效果后,给了我灵感,让我写下了这篇文章

链接链接 https://dev.to/yoniweisbrod/the-wizardry-of-css-animations-and-why-it-s-easier-than-you-think-3j5k
PREV
记住你为什么喜欢编程?“为什么”的重要性 你是如何进入编程世界的?我最初为什么喜欢编程?结论
NEXT
理解事件驱动架构