検索

この記事は、CSS アニメーションを始めてよく理解し、CSS アニメーションを使用して Web ベースのインターフェイスを実現し、アートに命を吹き込むのに役立つように書かれています。 W3C CSS アニメーション仕様はまだ改訂中ですが、現在では使用できる内容が数多くあります。

私にとって、CSS アニメーションで最もエキサイティングなことの 1 つは、使い慣れたツールを使用して CSS アニメーションをプロジェクトに簡単に追加できることです。すでに HTML と CSS に習熟している場合は、プロジェクトに動的な効果を追加するために新しい言語やプラグインを学ぶ必要はありません。 HTML と CSS だけで十分なので、これは非常に大きなメリットです。目を引くデザインの詳細をいくつか追加するか、大量のアニメーションを追加するかは問題ではありません。

CSS、JavaScript、SVG のトランジション属性はいずれも Web ページに動的な効果を加えることができ、どれも実験する価値がありますが、JavaScript と SVG の内容については本書では説明しません。 CSSアニメーションの仕様に焦点を当てます。

この記事をまとめる私の目標は、CSS アニメーションの可能性を認識してもらい、アニメーションの実験と作成のための強固な基盤を提供することです。この記事では、CSS アニメーションについて十分に説明し、創造力をさらに高めるのに十分な内容を提供します。

ブラウザ プレフィックスの概要

ブラウザ プレフィックスを十分に理解していないと、CSS アニメーションをうまく学ぶことができません。そのため、この記事でこの問題にどのように対処するかを少し見てみましょう。

この記事を書いている時点では、Firefox、Opera、IE はすべて接頭辞なしの CSS アニメーションをサポートしています~やったー!ただし、これらのブラウザの古いバージョンを含む他のブラウザでは、CSS アニメーションのサポートを提供するためにブラウザ プレフィックスを追加する必要があります。したがって、すべてのプロジェクトでアニメーション プロパティを接頭辞として付けることを強くお勧めします。ただし、それが必要であるとだけ言っておきましょう。

もちろん、実験中であるか、単にローカルでテストしている場合は、使用しているブラウザのプレフィックスを追加するだけです。製品版に到達したら、他のプレフィックスを追加するだけです。

読みやすいように、この記事のコード スニペットでは接頭辞のないバージョンを使用して CSS アニメーション プロパティを記述します。一部のコード スニペットにはプレフィックスが含まれており、編集してテスト実行できるいくつかの例も CodePen で入手できます。

さて、今からアニメーションの学習を始めましょう!

CSS アニメーションの基本

CSS アニメーションは非常に複雑に見えますが、そのコアとなるアニメーションの基本的な内容は非常に単純です。アニメーション名、キーフレーム、および動きの方向を決定するその他のコンテンツ。

CSS アニメーションを作成する基本的な要素から始めます。 CSS アニメーションには 2 つの主要な部分があります:

  • アニメーションを定義する
  • それを指定された HTML 要素 (または複数の要素) に割り当てる。

別の順序で記述することもできますが、最初にアニメーションを定義してから適用することをお勧めします。そのほうが私のプロセスに沿っています。

@keyframes ルール

CSS アニメーションを定義するには、まず @keyframes ルールを使用してキーフレームを宣言する必要があります。後で参照できるように、アニメーションに名前を付ける必要もあります。

たとえば、画面上を移動する車のアニメーションを作成した場合、そのアニメーションに drive などの名前を付けると、@keyframes ルールは次のようになります:

@keyframes drive {}

キーフレームとは

簡単に説明すると、つまり、キーフレームは、アニメーション プロセス全体で変更される属性のリストです (つまり、どの属性がいつ、どのように変更されるか)。

リストの各実行はアニメーションの反復とみなされます。アニメーション化されたプロパティへの変更を確認したい場合は、その変更をキーフレームにリストする必要があります。アニメーション化可能なプロパティのリストについては、Mozilla Developer Network にこれまでに見た中で最も包括的なリストがあります。

従来のアニメーションでは、キーフレームはアニメーションのキーポイントです。通常、これらのキー コンテンツはまず先輩漫画家によって描かれ、その後、すべてのキー フレームがスムーズに再生されるように、若手漫画家が各フレーム間のトランジション アニメーションを描きます。 CSS キーフレームも同様の方法で機能します。キーフレームを使用してアニメーションのさまざまなポイントでアニメーション プロパティ値を指定すると、ブラウザーがトランジションの各部分を自動的に埋めます。 After Effects や Flash などのソフトウェアを使用したことがある場合は、キーフレームの概念にすでに精通しているはずです。

キーフレームを定義する

アニメーションはキーフレームで構成されます! @keyframes 宣言では、キーワード from と to またはパーセントの 2 つの方法で定義できます。

非常に単純なアニメーションは、オブジェクトをある場所から別の場所に移動するだけかもしれません。この場合、キーワード from と to はキーフレームの定義に非常に適しています。

その名前が示すように、キーフレームを記述することでアニメーションの開始位置と終了位置を定義します。これを先ほどの単純な車のアニメーションに適用すると、車を現在位置(座標0)から右に400pxの位置に移動させて画面上を動かすことができます。

@keyframes drive {	from {		transform: translateX(0);	}	to {		transform: translateX(400px);	}}

在很多情况下,你会想要在不止两个状态之间定义动画,这样的话使用百分比会比较合适。

用百分比定义关键帧,从0%关键帧开始,以100%作为结束。0%到100%之间的任何数字都可以定义关键帧,所以使用百分比有非常大的灵活性。当然,如果你喜欢的话,你也可以将百分比和from、to混合使用。

如果我们在小车动画中使用百分比来定义关键帧,它是这样写的:

@keyframes drive {	0% {		transform: translateX(0);	}	100% {		transform: translateX(400px);	}}

正如你看到的,from相当于0%,而to则相当于100%。

如果你的关键帧列表中不包括0%或者100%,元素上现有的动画样式将会直接被用在0%和100%的的位置。此外,你不必按照严格的升序排列来列出百分比。一个0%的关键帧仍然会被认为是动画的第一个关键帧,即使它不是按照顺序排列的。这有很大的灵活性可以给关键帧分组,以便以后再查看。

将动画赋给HTML元素

一旦创建了关键帧声明块,就需要准备把动画赋给一个HTML元素或其它元素。我们还需要为HTML元素定义一个简短的属性列表,比如img元素,为它应用我们刚才创建的动画。

第一个属性是animation-name,用于告诉我们的图像,我们为它应用了哪组关键帧:

animation-name: drive;

第二个属性是animation-duration。我们的关键帧定义了整个动画的内容,但是我们并没有声明我们想要让它持续多长。可以把它设置为2s:

animation-duration: 2s;

animation-duration的默认值是0,这也就是为什么在我们看到动画出现之前,我们想要将它设置成其它值。它可以取秒(s)或微秒(ms)为单位。

只有设置了这两个属性以及我们刚才定义的关键帧,我们才可以看到动画。

我们完整的CSS是这样写的:

.car {	animation-name: drive;	animation-duration:1s;}@keyframes drive {	from {		transform: translate(0);	}	to {		transform: translate(400px);	}}

完成了!我们刚才只是完成了创建一个CSS动画需要的最基础的东西:一组定义好的关键帧;一个动画名称用于绑定HTML元素;以及动画的长度声明。

还有一件事……

有两个附加属性是我在所有的动画中都会显式定义的。一次性地完成动画而不再去修改(或是很长一段时间都不再去修改)的情况是非常罕见的。所以,我发现为我自己创建的每个动画都定义animation-timing-function和animation-iteration-count属性,这非常方便。

animation-timing-function属性

animation-timing-function属性的默认值是ease。但是,我建议你再显式设置一次这个值,因为它对于动画有非常大的影响(我们会在后面详细说一下它)。对于我们简单的小车示例,我把"timing function"值设置为ease-in:

animation-time-function: ease-in;

animation-iteration-count属性

animation-iteration-count属性也是很方便的一个属性,即使你使用的是默认值。这个属性决定了动画会重复播放多少次,它的默认值是1。

animation-iteration-count: 1;

作了这些补充之后,我们的最终CSS是这样的:

.car {	animation-name: drive;	animation-duration: 2s;	animation-timing-function: ease-in;	animation-iteration-count: 1;}@keyframes drive {	from {		transform: translate(0);	}	to {		transform: translate(400px);	}}

查看最终效果。作为我们的第一个示例动画,还是不错的。

探究动画属性

我们已经了解了CSS动画最基础的内容。它涵盖了非常多的内容,但是你很快很发现动画有不同的层,当你在完善动画的同时还想节省时间的时候,你就需要有更多帮助你控制动画的东西了。

幸运的是,有很多的属性可以让我们对CSS动画有更深层次的控制,也可以有更多的润色,让动画更丰富。

本节将着眼于animation-delay、animation-fill-mode和animation-direction这些属性的使用。我们将使用一个稍微复杂一点的动画,滚动的球,作为我们的下一个示例的基础。我已经创建了一个从左到右移动的球的动画,并通过几个关键帧来演示这些属性是如何派上用场的。这是我们的动画效果。

我们最初的CSS样式:

.ball {	animation-name: ballmove;	animation-duration: 2s;	animation-timing-function: ease-in-out;	animation-iteration-count: 1;}@keyframes ballmove {	0% {		transform: translateX(100px) rotate(0);	}	20% {		transform: translateX(-10px) rotate(-0.5turn);	}	100% {		transform: translateX(450px) rotate(2turn);	}}

animation-delay属性

在我们最初的示例中,动画是在我们加载页面完成后就立即运行的。那如果我们不想要动画怎么快就开始播放呢?这就是animation-delay上场的时候啦。animation-duration和animation-delay都接受以秒(s)和毫秒(ms)为单位的值,现在为动画设置2s的animation-delay。

animation-delay: 2s;

带有延迟的动画:

现在我们已经在球动画开始之前有了一个看起来不错的暂停。你可能注意到了,在动画结束的时候,我们的球会回到原来的位置。这不是结束一个动画最理想的方式。当你的对象在屏幕上移动,你可能希望它能停在结束的位置,而不是回到原来的位置。这就是animation-fill-mode可以完成的东西。

animation-fill-mode属性

animation-fill-mode属性可以接受四个值:none、backwards、forwards和both。如果你没有声明这个属性的话,默认值为none。在这个示例中,我们让关键帧一路把球移动到容器的右侧。但是在动画结束的时候,小球又回到了它的初始位置。这是因为animation-fill-mode:none的作用。当动画结束的时候,它会返回自己的初始位置。

我在CodePen上创建了一个示例,你可以为其添加或者改变animation-fill-mode属性的值,来看看结果是否有变化。

animation-fill-mode: forwards

但是,如果我们显式地设置animation-fill-mode为forwards,在动画结束之后,我们的小球会保持它最后一帧的样式;在这个示例中,100%的关键帧会把它放到右侧。我们给.ball这个类添加一个属性:

animation-fill-mode: forwards;

现在,我们的小球就会保持在我们动画结束的位置,这可能比较符合常理。效果如下。你可以想象成animation-fill-mode: forwards就是在动画播放过程中用于扩展最后一个关键帧的样式的。

animation-fill-mode: backwards

当使用延迟动画时,将动画的fill-mode设置为backwards非常方便。在我们的示例中,动画有一个2s的延迟,然后它先向左再向右移动。如果没有设置animation-fill-mode属性,在动画经过延迟之后,开始播放,小球会突然跳到0%关键帧定义的位置。这虽然不会像动画结束的时候它就突然回到起点这样,但是看起来还是不太好的。

如果我们加上一个animation-fill-mode属性并设置为backwards,小球就会在我们的animation-delay时变成我们0%关键帧定义的样式。你可以想象成它就是把0%关键帧位置的样式扩展到延迟的位置。

animation-fill-mode: backwards;

预览我们的示例来看看结果:

补充一下,如果没有0%(或from)关键帧,你的动画也可以在animation-delay的过程中先到达相应的位置。浏览器会使用已经应用到你的目标元素上的样式,作为你的动画的开始关键帧的样式,以替换缺省的初始关键帧,因此会在延迟过程中将你的目标元素先放到对应的位置。不过这并不总是可行的,取决于你项目的设置,有可能是其它的情况,不过有得选择总是好的。

animation-fill-mode: both

还有一个可选的值是both,正如它的字面意思,它是forwards和backwards的结合。动画可以在开始前就已经是第一个关键帧的样式,然后,在动画完成后,保持最后一个关键帧的样式。

回到我们的示例中。这种情况下,我们会使用both,这样我们的小球就会在它开始前就带有我们第一个关键帧定义的样式,在它结束之后会保持最后一个关键帧的样式。

animation-fill-mode: both;

我们最终的CSS是这样写的:

.ball {	animation-name: ballmove;	animation-duration: 2s;	animation-timing-function: ease-in-out;	animation-iteration-count: 1;	animation-delay: 1s;	animation-fill-mode: both;}@keyframes ballmove {	0% {		transform: translateX(100px) rotate(0);	}	20% {		transform: translateX(-10px) rotate(-0.5turn);	}	100% {		transform: translateX(450px) rotate(2turn);	}}

预览示例,查看结果:

animation-direction属性

还有另一个动画属性我想在这探讨一下,animation-direction。目前为止,我们的动画只能forward播放,而且运行效果也非常不错。但是我们还有其它的选择??有一个非常有用的属性!animation-direction,它的值可以是normal(正常),reverse(反转),alternate(交替)和alternate-reverse(交替反转)。它们听起来有点拗口,但是当你看到它们的使用情况时你就会觉得真是so good。我创建了一个示例,你可以添加或更改animation-direction属性的值来看看它们不同的效果。

它的默认值是normal,这个值是通过你列出的关键帧声明直接播放的。这儿有一个截图。

reverse设置表示你的动画是按照你的关键帧序列反向播放的,就像回绕播放一样。把direction设置为reverse,我们的小球就会从右往左跑了。

效果如下:

如果你的动画的iteration-count属性的值大于1,你可以使用alternate值。第一次按照正常的顺序播放,第二次就会反向播放,然后正向,然后反向……方向交替,从正向开始,直到iteration-count跑完。

效果如下:

最后,alternate-reverse是和alternate一样的意思,除了它是从反方向开始的。通过设置alternate-reverse属性,我们的小球和上一个示例一样交替迭代方向,只不过它是从一个reverse的方向开始的,而不是正常的方向。

如果你的观察力比较敏锐,你可能会注意到我们的animation-timing-function属性会随着animation-direction的反向一起反向,这是CSS动画一个很不错的内置效果。

通过这些简单的例子,我相信你可以发现这些属性对于CSS动画创建非常有趣的效果的用处之大。

简写

你可以使用简写来指定你的动画属性。Thanks god!一个animation定义的动画简写属性可能是这样的:

animation: myAnimation 1s ease-in-out 2s 4;

也就是:animation:

你可能注意到了在不同的示例中,简写属性的顺序不一样,虽然他们运行起来都没问题。在这个特殊的简写中,相似术语的顺序(比如持续和延迟的值)会比较重要。 W3C注意事项 :

该顺序在定义每个动画的时候都是非常重要的:第一个值解析为动画持续的时间,第二个值解析为动画延迟的时间。

W3C目前定义的简写顺序是这样的:

<single-animation> = <single-animation-name> || <time> || <single-animation-timing-function> || <time> || <single-animationiteration-count> || <single-animation-direction> || <single-animation-fill-mode> || <single-animation-play-state>

要使用简写在一个元素中定义多个动画,你需要使用逗号来分隔每个动画的属性值。比如在一个元素中定义两个动画需要这样写:

animation: myAnimation 1s ease-in-out 2s 4, myOtherAnimation 4s ease-out 2s;

理解easing

easing是什么?这一节都是关于easing的内容?没错!Easing是我觉得我们网页设计师目前还探讨得不够的内容之一。

“时间是动画的一部分,它为每一次移动赋予了意义。移动可以是通过简单地在两个不同的位置绘制相同的内容,然后在两者之间插入数个其它的图片来完成。但是这样屏幕上的看到的就只是单纯的移动,而不是动画。” ??Harold Whitaker and John Halas, Timing for Animation

而Easing有足够的能力去影响动画的交流。某一个对象是重要的,但是它到达相应位置的方式可能更重要得多。事实上, Timing for Animation 这本书详细地写了这方面的内容。虽然我们不太可能做到把动画绘制成像迪斯尼那样的,但是了解如果控制我们动画的移动还是很重要的。

这个移动传达的是对象什么样的情绪、分量和其它关键性格以及沟通的因素。这些移动或变化的过渡为我们提供了一个很好的激流的机会,尽管它们可能只会停留不到一秒的时间。

根据定义,Easing是速率被分配到整个动画过程中的方式。在CSS中,我们的easing是用animation-timing-function属性处理的。我们有三种定义timing的方式:关键字;自定义三次贝塞尔曲线;steps。steps在这里是奇数的,因为它们有自己独特的概念,所以它实际上并没有做任何的easing。我们将在最后的一部分内容中简要地探讨一下steps。

easing关键字

首先,我们来仔细地看一下预定义的关键字选项,来对幕后发生的事情有更进一步的了解。我们预定义的easing关键字是:ease(默认);linear;ease-in;ease-out和ease-in-out。

如果我们要使用linearEasing创建一个在两个关键帧之间一帧一帧线性移动的小球,它的运动效果如下:

对象以保持相同的速度在两个关键帧之间移动。速度从整个动画的开始到结束都是不变的。这通常会被视为非常机械的不自然的移动,因为在现实生活中,没有东西会像它这样以恒定的速度移动。

如果我们用ease-in创建相同类型的插图:

该移动在一开始的时候比较慢,然后在接近终点的时候慢慢加快速度。在一般情况下,这种easing类型创造了一种蓄势待发的加速感。对象在移动过程中的速度加快可以暗示其重量,还可以加上其他的外力来同它配合。

使用ease-out给了我们相反的感受。动画在一开始的时候速度比较快,然后随着慢慢接近终点,速度越来越慢:

结合ease-in和ease-out的概念,我们得到了ease-in-out,这个值会让对象在中点的时候速度上升到最快,在开始和结束的时候速度较慢。从ease值得到的Easing移动是ease-in-out的变体;ease在结束的时候有一个更剧烈的减速,但是你可以看到它们其实看起来是很相似的。个人而言,我更喜欢ease-in-out,因为在大多数情况下运动比较平衡。

贝塞尔曲线

值得庆幸的是,easing的值我们有不止五个关键字可以选择。在我们希望能够有更多的easing选择的时候,三次贝塞尔曲线来拯救我们了!上面的几个关键字也可以被定义为三次贝塞尔曲线。这些关键字有点像常见贝塞尔曲线的快捷方式。当你需要的控制比上边五个关键字提供的更多的时候,你可以为你的timing函数创建三次贝塞尔曲线,这样easing可选择的值就几乎是无限的!

创建曲线时,我们根据时间来计算动画的进展,然后得到这样的一条代表了动画过程中的速率的曲线。

lineareasing关键字对应的贝塞尔曲线

我们不需要去纠结它们背后的所有计算,因为我们的目的不在于此,尽管你对 贝塞尔曲线的基础 充满好奇心,想要研究它的每个数学方面的细节。理解曲线的关键是:曲线越陡峭代表速度越快,曲线越平坦代表速度越慢。下边这条曲线是ease-in-out关键字对应的贝塞尔曲线。中间是最陡峭,所以移动得最快,最后是平缓的,所以速度变慢了。

ease-in-out关键字对应的贝塞尔曲线

对曲线形状的小调整都会影响导致我们动画的细微差异。每条三次贝塞尔曲线都是通过四个在0和1这个范围之间的值定义的,这四个值用于表达曲线该如何绘制。

cubic-bezier(0.165, 0.840, 0.440, 1.000)

如果是像上边这样写,那它们对我们大多数人是没有意义的,因为根本不明白它们代表的意思。想要让你打破在数学课上使用旧图形计算器的习惯是需要相当一段时间的。幸运的是,我们可以使用一些工具来让这些数字的意义可视化,也更直观,方便我们理解。

创建三次贝塞尔曲线的工具

我最喜欢的三次贝塞尔曲线生成工具是, Matthew Lein 的 Ceaser ,提供了各种不同的预设,并允许你拖动点来创建你自己的贝塞尔曲线,还可以预览你创建的easing。当你对生成的东西满意的时候,你就可以复制它动态生成的代码,并把它放在你的CSS中使用。Ceaser还提供了和 Penner easing方程 (常用于Flash中,现已被移植到JavaScript、CSS等地方使用)等同的CSS。

在Ceaser中创建贝塞尔曲线

Ceaser不是唯一可以取得easing信息的地方, Easings.net 展示了一些可选的三次贝塞尔曲线的交互版本,以及由此产生的移动都在同一个地方。Lea Verou的 cubic-bezier.com 也可以让你创建、比较和分享三次贝塞尔函数。动画是一个可视化的东西,所以有这些可视化编辑器和工具来帮助你取得你想要的移动效果是非常好的。这比靠猜数字来想象更有效得多。

现在我们已经对CSS中的easing有了相对深入的了解,你可以通过对你的动画进行微调,做出合适的easing选择,让你得到需要的运动和信息。

如果这里讨论的easing,timing和动画原则激起了你的兴趣,我强烈推荐你阅读一下 迪斯尼动画的十二个基础原则 ,还有 Timing for Animation 、 The Animator’s Survival Kit 这两本书。传统动画工艺有非常丰富的历史,值得我们去学习。

Timing函数并不是万能的

经过前面关于timing函数可以做的东西的这么多的介绍,有一个更重要的点是,CSS要如何使用我们定义的timing函数。对于关键帧动画,timing函数是在关键帧之间应用的。在很多情况下,你只能给每个动画指定一个timing函数:

.someClass { animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); }

在这种情况下,你的三次贝塞尔函数会在动画中的每个关键帧之间应用。这将决定所有属性之间的移动样式,都会按照你在keyframes中定义的函数运动。

但这并不总是理想的,尤其是那些复杂一些的动画。当你要制作的是比较复杂的运动时,在所有的关键帧之间应用相同的easing,几乎是不可能的。一开始的时候它看起来可能会很奇怪,但是我们可以改变timing函数,将它应用于@keyframes声明块中的中期动画。

@keyframes myAnimation {	0% { 		opacity: 0.5; 	}	50% {		opacity: 0.3;		animation-timing-function: ease-in-out;	}	100% { 		opacity: 1; 	}}

在上面的代码中,一个ease-in-out的时间函数会被应用在50%到100%的关键帧之间,但是之前设置的时间函数将会被默认用于0%到50%关键帧之间。

常见的动画任务

选出最常见的动画基本是不可能的,所以我选了几个示例,包括了一些我认为CSS动画可以使用的比较有用而且有趣的内容。在这里我们将详细讲解每一个示例,把你CSS动画方面的知识应用到实际中。我特意选了那些HTML相当简单的例子,这样我们就可以专注于CSS以及那些驱动动画的特定属性。

无限循环的背景动画

CSS制作这种类型的动画是非常棒的,它可以很简单地建立一个无限循环。为了展示它是如何运行的,我们将创建几朵在天空中飘动的动画云朵。在CodePen上有这个 示例 ,你可以跟着代码学习,接着往下看。

看一下初始的CSS,对于上边的云朵,我们使用了共享的类样式,为它们设置了背景图片、宽度和高度。我们单独为每朵云设置了不同的位置值以及z-index的值,来把它们错开:

.cloud {	width: 248px;	height: 131px;	position: absolute;	background: transparent url(../images/cloud.png) 0 0 no-repeat;}.cloud01 {	top: 100px;	left: 300px;	z-index: 100;}.cloud02 {	top: 240px;	z-index: 200;}

现在我们就来让这些云动起来吧!首先,我们先在keyframes中定义动画,把它命名为drift。让这些云动起来,飘过天空。因为我们不希望云在漂移的过程中有任何停顿,所以它们看起来好像完全适合用from、to关键帧。所以,我们的keyframes应该这样写:

@keyframes drift {	from {		transform: translateX(-255px);	}	to {		transform: translateX(1350px);	}}

这里的关键点是,我选择了一个离左边较远的from值(让云从我们看不见的地方开始飘动),一个离右边较远的to值(让云飘到我们看不见的地方结束)。为了更好的性能,我使用了translate,而不是在keyframes中不同定位(尽管在这样一个小例子中,这点异微不足道)。另外,因为我不可能对所有特定的布局都使用translate,所以可以肯定地说,我的动画不会造成任何布局上的问题或者是无意的覆盖布局样式。这个例子比较简单,所以我们不需要考虑这个问题,但是将动画样式和布局样式分开是一个好习惯。

下一步,我们将为这些云指定同一个动画,只是设置的属性略有不同,但是使用的都是相同的keyframes。把动画的定义以及引用分开,可以很方便地重用动画。对于第一朵云,我们给它指定这个drift动画,持续时间是25s,因为云朵都是慢慢飘的~接着把animation-timing-function的值设置为linear,让它在移动的过程中都保持相同的速度。然后定义我们的animation-iteration-count属性,这可以让我们的云朵在天空中一次又一次地飘啊飘啊飘啊~~无限循环。

.cloud01 { animation: drift 25s linear infinite; }

对于第二朵云,我们使用了相同的动画,但是设置相对复杂一点。我们设置了持续时间为35s,这样它可以比我们的第一朵云飘得更慢更稳~另外,我们还把这个动画延迟了10s,把animation-fill-mode设置为backwards。这样我们的云朵就会在那10s的延迟内先到达我们第一个关键帧(from关键帧)的位置。

.cloud02 {animation: drift 35s linear 10s infinite backwards;}

如果我们预览 我们最后的代码 ,两朵云的动画是不一样的,尽管我们使用了相同的keyframes。

能够像这样在多个元素上重用动画,是CSS一个非常有用的特性。只要让它们的属性稍有不同,就可以让相同的一组关键帧变得非常万能。

使用steps让雪碧图动起来

前面提到过steps,现在就来讲一下。Steps和我们的另一个animation-timing-function的其它选项表现得非常不一样,它们有它们自己的怪癖和复杂性。它们通常用于结合雪碧图来创建幻灯片,或一帧一帧的动画。如果你想跟着代码一起来看,可以查看下面示例。

构建网站时经常使用雪碧图,来作为一张大图内包括了很多的小图标或是你在网站上使用的其它的图片。对于动画,雪碧图以类似的方式工作。我们把动画的每一帧都收进了一张图片内,把这张图片作为某个div的背景,然后通过移动背景图片来创建动画。steps用于定义在动画过程中你的背景图片有多少次停顿。

Steps把动画的持续时间根据steps的数量分成了相同的若干部分。这每一个steps就像你动画的帧,不同的是你的动画将被分成一系列停顿,而不是持续的运动。

对于这个示例,我们将使用一个由我的朋友??动画师 Scott Benson 绘制的角色步行循环。他在After Effects中把这个短短的步行循环作成系列png格式的图片导出,然后我把Photoshop中把它们集中到了一张雪碧图上。(我发现自动雪碧图生成器对于像这样的雪碧图并不好用,所以我使用了Photoshop来制作。)

在CSS中,我们先给div指定width和height的值,让它和我们动画的尺寸相匹配,然后设置背景图像为我们创建的雪碧图。

.sprite {	width: 245px;	height: 400px;	display: block;	background: transparent url(../images/walker.png) 0 0 no-repeat;	margin: 3em auto;}

和其它的timing函数一样,steps使用一组关键帧来定义动画。所以,我们会创建一个keyframes定义,把它命名为walker,然后定义两个关键帧。

@keyframes walker {	0% {		background-position: 0 0;	}	100% {		background-position: 0 -4000px;	}}

我们的雪碧图的总高度是4000px,我们在这里使用了一个负值,让图片上移。在我们的雪碧图上移的时候,我们的图像中下面的关键帧就会被显示出来。通过上面的关键帧,我们把图像从0 0的位置跳到0 -4000px的位置。

我们可以通过删除0%关键帧来简化这个动画。如果我们没有特别定义一个起始关键帧(在这里,指0%关键帧),之前应用到我们元素的样式将会被作为起点使用。当我们在.sprite类中指定背景图像时,我们已经把背景图像的位置为0 0,所以我们不需要在关键帧中重复。我们稍微简化了的关键帧如下,隐含了第一个关键帧:

@keyframes walker {    100% {        background-position: 0 -4000px;    }}

随着我们的动画定义完成,我们把它指定给我们的.sprite类来获得动画效果。我们将walker动画指定给类名为.sprite的div,给它1秒的持续时间。(如果你想要动画播放得快一些或者慢一些,可以调整duration的值。)我们把animation-timing-function设置为steps(10),表示把动画的持续时间分成10份。10也是雪碧图中帧的数量,这样在动画播放的时候,每一帧都可以看到。

最后同样重要的是,把animation-iteration-count设置为infinite。这个雪碧图将会一直循环下去,这样我们可以看到我们的角色一直一直都在步行。我们给.sprite类添加的属性如下:

.sprite { animation: walker 1s steps(10) infinite; }

你可以在这里查看 最后的动画效果 。

使用animation-play-state来启动或停止动画

默认情况下,动画在它们被分配好的时候就立即开始播放,但是我们可以控制它开始播放的时间。根据我们给它们指定的位置的不同,或者选择播放暂停的时间,可以得到非常有趣的结果。可以把hover或类似性质的事件作为触发器,分配动画或改变动画的属性。当然,如果你把JavaScript和CSS动画结合起来使用,你还可以得到更复杂的交互,可以得到的效果也就更多。不过hover状态是可以独立完成CSS各种效果的。比如说,在hover时创建一个比只有过渡更多的悬停动画效果。

结合前面的那个例子,如果你方便在浏览器中查看的话,你可以看看下面的示例:

这个示例是一个带有文本的标签,在我们鼠标悬停时会旋转,可以多留意一些很棒的新东西。我们先来定义能让我们的标签动起来的动画:

@keyframes spin {    100% {        transform: rotate(1turn);    }}

我们把这个动画赋给我们的标签,这是一个div元素,设置类名为.sticker。另外,我们在第二行中把animation-play-state的值设置为paused:

.sticker {    animation: spin 10s linear infinite;    animation-play-state: paused;}

animation-play-state的值有两个,running或paused。默认值是running,除非你另外设置了。

如果你现在预览文件,你不会看到任何效果。我们给标签设置了旋转,但是又让它暂停了。为了看到我们努力的成果,我们需要把animation-play-state在某个状态的时候设置为running,在这个例子中,hover就OK了:

.sticker:hover { animation-play-state: running; }

这样,在我们的鼠标悬停的时候,标签就会旋转了;在我们鼠标离开的时候,它就停止旋转;然后我们的鼠标再次悬停在上面的时候,它就从上次离开的地方开始接着旋转。我们不是只在两种不同的状态之间直接切换,在每次hover的时候,我们展示的是一大段变化中的一部分。切换animation-play-state的值,比非传统的hover效果多了一些更多有趣的选项。在一些线性动画中,它是一个很方便的让动画停止的方法,然后在你一切准备好的时候开始播放。

我们完成的CSS代码如下:

body {	padding:4em; 	background: #fcfcfc;}.wrap {	width:200px; 	margin:auto; 	position:relative;}.msg {	color: whitesmoke;	text-align: center;	font-family: serif;	font-size: 3.5em;	width: 200px;	position: absolute;	margin: 55px 0 0 2px;	pointer-events: none;}.sticker {	width: 200px;	height: 200px;	position: absolute;	background: url(../images/sticker.png) top center no-repeat;	animation: spin 10s linear infinite;	animation-play-state: paused;}.sticker:hover {	animation-play-state: running;}@keyframes spin { 	100% {transform: rotate(1turn); } }

查看最后完整的示例

如果把JavaScript和CSS动画结合起来使用,就可以做出更强大的交互效果,而且我也希望你能这样做。你肯定会有兴趣去了解在CSS动画开始、进行和结束的时候,JavaScript中都有哪些动画事件可以使用。它们超出了我这本指南的内容,但是 Mozilla Developer Connection中有非常精彩的介绍 , Craig Buckler也会引导你去了解各个不同的浏览器命名的差异 (因为,当然,浏览器制造商并不同意把它们统一命名)。

多个动画,一个对象

目前为止,我们讨论的都是为单个元素应用单个动画,但是我们可以为对象添加不止一个动画,只要我们需要。最常见的方法是动画一前一后,这样动画就可以一个轮着一个播放。巧妙地设置animation-delay属性的值可以让我们用纯CSS来完成这个效果。

如果是让两个动画同时作用在相同的元素上,可能比较有技术性。但是CSS不能把两个或者更多keyframes集合组合起来,所以这样设置的结果通常并不是我们想要的。

为了展示如何把多个动画组合起来,我们让一个小奖章从左边滚入,然后在到达指定的位置前进行缩放。示例如下:

首先我们用keyframes创建两个动画。如果这不是在一本书的上下文中,在到达最后的动画之前会有很多次的调整和预览。但是我们必须跳过这些发现乐趣的步骤,直接看这两个关键帧动画:

@keyframes roll-in {	0% {		transform: translateX(-200px) rotate(0deg);	}	100% {		transform: translateX(0) rotate(360deg);	}}@keyframes scale-up {	0% {		transform: scale(1);		animation-timing-function: ease-in;	}	25% {		transform: scale(1.15);		animation-timing-function: ease-out;	}	60% {		transform: scale(0.9);		animation-timing-function: ease-in;	}	100% {		transform: scale(1);		animation-timing-function: ease-out;	}}

使用第一个keyframes声明来让我们的奖章(一个div元素,指定其类名为.mol)从左边滚入。它只有两个帧,从左侧移动到右侧,并加入一些旋转。很适合使用from和to来定义关键帧,但是我喜欢统一使用一种方法。

第二个动画是让奖章的大小来回弹动,让它在结束的位置有弹性地结束动画。我们甚至可以改变timing函数,来对它的弹动效果进行微调。

我们需要把这两个动画设置为是一个接一个播放的,把第二个动画的延迟时间和第一个动画的持续时间的值设置相同即可:

.mol {	animation-name: roll-in, scale-up;	animation-duration: 1s, 0.75s;	animation-delay: 0s, 1s;	animation-timing-function: ease-in, linear;	animation-iteration-count: 1;	animation-fill-mode: forwards;}

把动画属性用逗号分隔开,在罗列动画名字的时候,应该按照相同的顺序。在这种情况下,1s、0s和ease-in都是第一个值,与roll-in动画相关,因为它被命名为第一个,然后第二个值是scale-up。在任何情况下,如果我们只指定了一个值,如animation-iteration-count,它就会被用于两个动画。

把第二个动画的延迟设置为1s,和第一个动画的持续时间保持一致,这样就可以在第一个动画结束的时候马上执行。我们可以持续添加更多的动画,然后相应地调整延迟和持续时间,但是在这个例子中,我们只写了两个,这两个回转动画最后的CSS如下:

.mol {	width: 174px;	height: 174px;	background: transparent url('../images/mol_badge.png') top center no-repeat;	position: absolute;	left: 400px;	animation-name: roll-in, scale-up;	animation-duration: 1s, 0.75s;	animation-delay: 0s, 1s;	animation-timing-function: ease-in, linear;	animation-iteration-count: 1;	animation-fill-mode: forwards;}@keyframes roll-in {	0% {		transform: translateX(-200px) rotate(0deg);	}	100% {		transform: translateX(0px) rotate(360deg);	}}@keyframes scale-up {	0% {		transform: scale(1);		animation-timing-function: ease-in;	}	25% {		transform: scale(1.15);		animation-timing-function: ease-out;	}	60% {		transform: scale(0.9);		animation-timing-function: ease-in;	}	100% { 		transform: scale(1); 	}}

性能及浏览器支持情况

同往常一样,当我们在使用一些大家认为是很新的东西时,需要确保广泛的跨浏览器的良好体验。确定浏览器支持之后,针对缺乏支持的情况做好良好的计划,这对你创建动画来说是一个良好的开始。

CSS动画 vs JavaScript动画:谁更厉害?

在测试的时候,如 这篇发表在欧朋开发者blog上的文章 ,都表明了CSS动画确实渲染得更快,而且比等效的JavaScript占用更少的内存。这是由于渲染CSS动画更多的是由浏览器内部完成的,这提高了很多效率。

CSS动画还受益于硬件加速性能的提高,尤其是Paul Irish的 这篇文章中 展示的使用transform的demo。

这些demo,以及那些类似的,都展示了CSS在很多情况下,相比JavaScript有更多提高性能的潜力。你的情况可能因你的目标浏览器而有不同,这正是完成动画任务的关键。但总体而言,CSS动画是一个有力的竞争者。我想我们可以期待一下这些潜在的性能优势能随着浏览器的发展而有所提高。

目前的浏览器支持情况

caniuse.com 网站提供了关于浏览器支持最详细的信息。它提供了一个方便查看的图表,显示了哪些浏览器版本支持动画,以及哪些前缀是必须添加的。当你对某个CSS属性的当前或过去的浏览器支持感兴趣的话,可以随时查看这个资源。

如果你要创建一个基于安卓受众的东西,你需要关注CSS动画规范在安卓浏览器3.0及以下版本中的支持情况。部分支持比不支持更麻烦,因为我们并不清楚到底哪部分是支持的哪部分是不支持的。Daniel Eden对于比较旧的安卓浏览器 提供了一些有用的建议 。

不管怎样,只要你想要测试某特定的设备或浏览器版本对项目的支持情况的话,最好先进行全面的测试并确保在那个环境中是可以运行的,以确保它能支持,而且有良好的性能。

但是当动画在不同的浏览器中渲染时,仍然有一些比较小的古怪差异,没有办法得到完全的支持。我希望这种bug会随着动画慢慢成熟的支持支持慢慢地较少。但是目前,你可能还是偶尔会碰到这种情况,因为CSS动画还是一块比较新的内容。

现在可以使用CSS动画了吗?

CSS动画有很广泛的支持,现在我们还是希望在现代浏览器的圈子中,每个人都能看到我们做的web。可惜的是CSS动画还没有完全得到目前使用中的所有浏览器的支持,绝对不行。在生产工作中使用CSS动画需要考虑缺乏浏览器支持的情况,因为除非你的受众非常小众,不过你也只能偶尔碰到一两个。所以制作CSS动画大部分的工作量在于,你需要根据你使用CSS动画的具体情况,为它准备好fallback。

用于细节设计的动画

只为非必要的效果和细节设计使用CSS动画的时候,一个什么都不做的方法往往会导致一个可接受的fallback。浏览器会忽略它们无法解析的CSS,所以如果你提前计划,确保你的网站在不能加载动画的时候,看起来不会非常糟糕,那就ok了。

一定要确保添加的动画只是作为额外的非必要的效果或细节,而不是任何影响到布局或重要任务的关键。我发现使用transforms变换和其它不太可能用于的属性,可以帮忙将布局和动画样式分离,所以关注一下那些应用了动画的元素,在没有动画的情况下展示如何。在你酝酿那些你可能并不真正需要的库和fallback之前,测试一下那些do-nothing的方法究竟是干嘛的。

記事の冒頭に、雲の無限ループのアニメーションの例があります。アニメーション プロパティをサポートしていないブラウザでこの例を表示すると、空に 2 つの雲が浮かんでいるのが見えます。アニメーションの一部として画面の内外を浮遊できる必要があるため、それらを画面の外に移動しました。何もない空を見るよりも、2 つの静止した雲が見える方が良いため、この場合、これは完全に許容できる結果です。

基本アニメーション

重要なエフェクトや重要なコンテンツを含むアニメーションを扱う場合、処理やテストを行わないことは絶対に不可能です。この場合、フォールバックを実装するか、CSS よりも幅広いブラウザーをサポートするものを使用してアニメーションを作成するという 2 つのオプションがあります。

正気を保ち、同僚との友情を維持するには、どうしても必要な場合や重大なメリットがある場合を除き、作業の重複 (CSS と JavaScript で同じアニメーションを記述するなど) を避けてください。同じものの 2 つのバージョンを作成することは、特に頻繁にメンテナンスする必要があるプロジェクトの場合には良い考えではありません。この種のプロジェクトで、古いブラウザの重要なサポートを必要とする重要なコンテンツを含むアニメーションが発生した場合は、JavaScript を使用して問題を解決するのが最善の選択肢です。

たとえば、CSS でスライド遷移アニメーションを作成する場合、JavaScript のフォールバックは、より多くの状況、特にほとんど変更する必要がない状況に適用できます。ただし、Web サイト上の頻繁に更新される機能モジュールの場合、特別なアニメーションごとに CSS および JavaScript バージョンのアニメーションを作成することは、間違いなく時間の無駄です。

実験的プロジェクトやエンターテイメント プロジェクトでは、より幅広い視聴者にリーチするために、いくつかのフォールバックが役立つ場合があります。満足度を下げるのは困難ですが、Modernizr のようなツールを使用すると、どのブラウザが満足度をサポートしているのか、どのような調整が必要なのかを把握できます。コードの JavaScript バージョン、古いバージョン、またはプロジェクトで実行できる別のバージョンが提供される場合があります。

フォールバックに注意し、ユーザーのブラウザが私たちが使用したいものではないこと、またはユーザーを引き付けるのに役立つその他の方法をユーザーに伝えないでください。作成したアニメーションが実際にユーザーのブラウザーやデバイスで適切に動作しない場合は、最も重要なコンテンツを隠さずにユーザーに提供するようにしてください。

制作ジョブで CSS アニメーションを使用できない場合でも、心配する必要はありません。 CodePen や JS Bin など、練習用のプラットフォームやコミュニティを提供する Web サイトがたくさんあります。

結論

CSS アニメーションを学ぶこの旅を楽しんでいただければ幸いです。これは CSS アニメーションで実現できることのほんの紹介にすぎず、動きを美しいデザインの詳細に変換して Web サイトに表示することは始まりにすぎません。これらの例とリソースを練習の始まりとして使用し、独自のプロジェクトで CSS アニメーションを使用してみてください~~O(∩_∩)O

この記事は、@Val Head の電子書籍「CSS アニメーション」に基づいて編集されています興味があれば、この電子書籍を購入できます: http://www.fivesimplesteps.com/products/css-animations。

原文 http://www.w3cplus.com/css3/CSS3-animation.html

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
HTML、CSS、およびJavaScriptの理解:初心者向けガイドHTML、CSS、およびJavaScriptの理解:初心者向けガイドApr 12, 2025 am 12:02 AM

webdevelopmentReliesOnhtml、css、andjavascript:1)htmlStructuresContent、2)cssStylesit、および3)Javascriptaddsinteractivity、形成、

HTMLの役割:Webコンテンツの構造HTMLの役割:Webコンテンツの構造Apr 11, 2025 am 12:12 AM

HTMLの役割は、タグと属性を使用してWebページの構造とコンテンツを定義することです。 1。HTMLは、読みやすく理解しやすいようなタグを介してコンテンツを整理します。 2。アクセシビリティとSEOを強化するには、セマンティックタグなどを使用します。 3. HTMLコードの最適化により、Webページの読み込み速度とユーザーエクスペリエンスが向上する可能性があります。

HTMLとコード:用語を詳しく見るHTMLとコード:用語を詳しく見るApr 10, 2025 am 09:28 AM

htmlisaspecifictypeofcodefocuseduructuringwebcontent

HTML、CSS、およびJavaScript:Web開発者に不可欠なツールHTML、CSS、およびJavaScript:Web開発者に不可欠なツールApr 09, 2025 am 12:12 AM

HTML、CSS、およびJavaScriptは、Web開発の3つの柱です。 1。HTMLは、Webページ構造を定義し、などなどのタグを使用します。2。CSSは、色、フォントサイズなどのセレクターと属性を使用してWebページスタイルを制御します。

HTML、CSS、およびJavaScriptの役割:コアの責任HTML、CSS、およびJavaScriptの役割:コアの責任Apr 08, 2025 pm 07:05 PM

HTMLはWeb構造を定義し、CSSはスタイルとレイアウトを担当し、JavaScriptは動的な相互作用を提供します。 3人はWeb開発で職務を遂行し、共同でカラフルなWebサイトを構築します。

HTMLは初心者のために簡単に学ぶことができますか?HTMLは初心者のために簡単に学ぶことができますか?Apr 07, 2025 am 12:11 AM

HTMLは、簡単に学習しやすく、結果をすばやく見ることができるため、初心者に適しています。 1)HTMLの学習曲線はスムーズで簡単に開始できます。 2)基本タグをマスターして、Webページの作成を開始します。 3)柔軟性が高く、CSSおよびJavaScriptと組み合わせて使用​​できます。 4)豊富な学習リソースと最新のツールは、学習プロセスをサポートしています。

HTMLでの開始タグの例は何ですか?HTMLでの開始タグの例は何ですか?Apr 06, 2025 am 12:04 AM

Anexampleapalofastartingtaginhtmlis、それはaperginsaparagraph.startingtagsaresentionentientiontheyinitiateelements、definetheirtypes、およびarecrucialforurturingwebpagesandcontingthomedomを構築します。

CSSのフレックスボックスレイアウトを使用して、メニューの点線のラインセグメンテーション効果のセンターアラインメントを実現する方法は?CSSのフレックスボックスレイアウトを使用して、メニューの点線のラインセグメンテーション効果のセンターアラインメントを実現する方法は?Apr 05, 2025 pm 01:24 PM

メニューで点線のラインセグメンテーション効果を設計する方法は?メニューを設計するときは、通常、皿の名前と価格の間に左右に合わせることは難しくありませんが、真ん中の点線またはポイントはどうですか...

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン