Skip to content

Latest commit

 

History

History
492 lines (346 loc) · 28.7 KB

第16章.md

File metadata and controls

492 lines (346 loc) · 28.7 KB

第16章 动画

本章内容

  • 使用关键帧动画为页面添加复杂运动
  • 页面加载的时候使用动画
  • 使用旋转器动画提供反馈
  • 吸引用户对保存按钮的注意力,提醒用户去保存

在前面两章里,我们创建了几种过渡行为,可以使元素从某种状态平滑变换为另一种。这为为页面带来了动态的效果,用户体验上也增加了视觉趣味性。但有时候仅仅使用过渡还不够。

过渡是直接从一个地方变换到另一个地方,相比之下,我们可能希望某个元素的变化过程是迂回的路线。有的情况下,我们可能需要元素产生动画运动之后再回到起始的地方。这些事情没办法使用过渡来实现。为了对页面变化有更加精确的控制,CSS提供了关键帧动画。

关键帧(keyframe)是指动画过程中某个特定时刻。我们定义一些关键帧,浏览器负责填充或者插入这些关键帧之间的帧图像(图16.1)。

图16.1 定义关键帧之后,浏览器插入所有关键帧之间的帧图像

[p397 图一]

Interpolated frames 插入的帧图像

从原理上看,过渡其实和关键帧动画类似:我们定义第一帧(起始点)和最后一帧(结束点),浏览器计算所有中间值,使得元素可以在这些值之间平滑变换。但使用关键帧动画,我们就不再局限于只能定义两个点,而是想加多少加多少。浏览器负责填充一个个点与点之间的值,直到最后一个关键帧,最终生成一系列无缝衔接的过渡。

在这最后一章,我们将会介绍如何创建关键帧动画。我们会在前一章创建的页面中添加一些动画,然后探索一些其他的使用方式。动画并非只能做一些让页面变得生动的事情,还能向用户传达一些有意义的反馈。

16.1 关键帧

CSS中的动画包括两部分:用来定义一组动画的@keyframes规则和为元素添加动画的animation属性。

下面我们创建一个简单的动画来熟悉一下语法。动画包含三个关键帧,如图16.2所示。第一帧中元素是红色的;第二帧中元素是浅蓝色,并且向右移动了100px;最后一帧中,元素是淡紫色,并且回到了左侧的初始位置。

图16.2 三个关键帧,分别对元素的颜色和位置添加动画

[p397 图二]

动画对background-colortransform这两个属性做了一些改动。关键帧规则已经列到了下面的清单中,新建样式表styles.css并添加这些代码。

清单16.1 定义关键帧规则

[p397 代码清单一]

[p398 代码清单一]

Names the animation 为动画命名

First keyframe declarations 第一个关键帧声明

Second keyframe occurs halfway through the animation 第二个关键帧发生于动画进行到一半的时候

Final keyframe 最后一个关键帧

关键帧动画都需要名字,示例中的动画被命名为over-and-back。动画中使用百分比定义了三个关键帧。这些百分比代表每个关键帧发生于动画过程中的哪个时刻:一个在动画的开始(0%),一个在中间(50%),一个在终点(100%)。每个关键帧块内的声明定义了当前关键帧的样式。

示例中同时为两个属性添加了动画,但我们注意到并不是每个关键帧都设置了两个属性。transform把元素从初始位置移动到右侧,然后再移回原位。但background-color在50%的关键帧中并没有指定。这意味着元素将会从红色(0%的位置)过渡到淡紫色(100%的位置)。在50%的位置,背景颜色恰好是这两个颜色的中间值。

下面我们把这些代码添加到网页中查看工作情况。新建一个HTML文档并添加下列代码。

清单16.2 只有一个盒子元素的网页,为盒子添加动画

[p398 代码清单二]

The element you’ll animate 即将添加动画的元素

接下来在样式表中为盒子添加样式并应用动画,可以复制下面清单中的代码。

清单16.3 为盒子应用动画

[p398 代码清单三]

Gives the element a height and width for demo purposes 为元素添加宽高以便于演示

Applies the animation to the element 为元素应用动画

在浏览器中打开网页,你会看到动画重复执行了三次,然后停下。animation属性是好几个属性的简写。在这个demo中,我们实际上指定了四个属性:

  • animation-nameover-and-back)——代表动画名称,就像@keyframes规则定义的那样。
  • animation-duration1.5s)——代表动画持续时间,在本例中是1.5秒。
  • animation-timing-functionlinear)——代表时序函数,用来描述动画如何加速和(或)减速。可以是贝塞尔曲线或者关键字值,就像过渡使用的时序函数一样(ease-inease-out等等)。
  • animation-iteration-count3)——代表动画重复的次数。缺省的时候,默认值是1

刷新页面,再次查看动画播放,观察动画执行过程中的几个地方:

第一,颜色从0%的红色平滑过渡到100%的淡紫色,但是接下来动画重复的时候立即变回红色。如果你打算重复某个动画并希望整体衔接流畅,需要确保结束值和初始值相匹配。

第二,最后一次重复动画结束之后,背景颜色变为绿色,即原样式规则中指定的值。但要注意动画持续过程中,这句样式声明被@keyframes中的规则覆盖了。如果出现样式层叠,动画中设置的规则比其他声明拥有更高的优先级。

我们回顾一下第一章(第1.1.1节),层叠的第一部分是介绍样式表的来源。作者样式优先级高于用户代理样式,因为作者样式有比较高的优先级来源。但动画中应用的声明有更高的优先级来源。为某个属性添加动画的时候,会覆盖样式表中其他地方应用的样式。这就确保了关键帧中所有的声明可以互相配合完成动画,而不用关注动画之外对这个元素可能应用了哪些样式。

警告

浏览器对动画的支持情况比较好,仅有小部分手机浏览器需要使用-webkit-前缀,动画属性(-webkit-animation)和关键帧@规则(@-webkit-keyframes)都要用到。这就需要复制出有前缀和无前缀两套代码。可以考虑使用Autoprefixer来实现(见第五章附加栏目"浏览器前缀")。

16.2 为3D变换添加动画

接下来,我们开始在前一章创建的网页上添加动画。完成清单15.10之后,我们已经有了一个蓝色背景的页面,页面左侧有导航菜单。我们会用几张卡片元素来填充页面剩余的部分。我们先完成整个效果图的页面排版,然后再添加动画。

16.2.1 创建无动画页面布局

在这个demo中,我们会在页面主区域添加一些卡片(图16.3)。然后再使用3D变换添加动画,使卡片具有飞入效果。

图16.3 页面主区域添加的卡片

[p400 图一]

下面的清单展示了这部分内容的代码,把这些代码添加到页面上<nav>元素的后面(为了节省空间,代码中卡片内的文字有删节。如果想要更加贴近图16.3中的快照图片,可以随意添加更多内容)。

清单16.4 创建飞入网格和几张卡片

[p401 代码清单一]

Grid container

网格容器

Cards are also grid items.

卡片同时也是网格元素

这部分页面由两个部分组成。外层的模块是“飞入网格”(Flyin-Grid),为网格内的元素提供布局,同时还包含了3D飞入效果,接下来会讲到。每个网格元素都是内层的卡片模块的一个实例。卡片模块提供外观样式,包括白色背景、内边距和字体颜色等。

这种排版首选网格布局,接下来就会用到。同时我们也应该考虑到移动设备布局,以及在不支持网格的老式浏览器中基于弹性盒布局的回退方案。我们首先实现移动布局,然后添加弹性盒样式,最后是基于网格的样式。

移动布局效果展示在了图16.4中。在小屏幕上,卡片会占满屏幕的宽度,只留左右两侧一点外边距。

图16.4 移动布局中,卡片会占满屏幕宽度,叠放在菜单下方

[p402 图一]

添加下面的移动样式到样式表中。

清单16.5 卡片的移动样式

[p402 代码清单一]

Adds a small left and right margin around the container

在容器左右两侧添加很小的外边距

Applies card colors and other details

为卡片添加颜色和其他细节样式

Specifies the image should fill the card width

设置图片应该填满整张卡片的宽度

在这样的屏幕尺寸下,飞入网格很容易实现,因为网格元素只需要像普通块级元素一样叠放。每张卡片都设置了白色背景和简单的外观样式。很快我们就会使用媒体查询设置更加复杂的布局。

接下来,我们使用flexbox添加回退布局,这只会应用在较大的屏幕上。这样就比较接近最终的效果图(图16.3)了。添加下面的CSS到样式表中。

清单16.6 使用基于flexbox的回退布局

[p403 代码清单一]

Responsive breakpoint

响应式布局的断点

Establishes the flex container with wrapping

建立允许折行的弹性容器

Increases padding on sides

增加两侧的内边距

Enables flex-grow and sets a flex-basis of 300 px

允许flex-grow,设置flex-basis为300px

这段代码使用flexbox创建了一个响应式布局。我们设置了flex-wrap: wrap,这样弹性元素在同一行放不下的时候允许折行。弹性基准值300px指定了元素的最小宽度,同时max-width指定最大宽度,在这些约束下,需要的时候元素就会折行。flex-grow的值为1,允许卡片拉伸填满容器的剩余空间。

卡片模块不需要在之前添加的移动样式基础上做任何改变,所有的颜色及其他样式都和之前一样。

在某些特定的屏幕尺寸下,卡片表现得和最终布局一致。但如果最后一行的卡片数量少于上面每行的卡片数量,卡片宽度不会总是相同。这个问题展示在了图16.5中。

在这样的视口宽度下(大约1000px),第一行刚好放入三张卡片,第二行只剩下了一张卡片。最后的这张卡片宽度拉伸到max-width的600px,使得它比其他卡片明显大出一截。缩小屏幕尺寸允许放下两行,每行只有两张卡片,那所有卡片的尺寸就会相同,因为每行的卡片数量一样多。一旦改变屏幕尺寸,可能又会出现这种问题。除了屏幕尺寸,还跟一共有多少张卡片有关系,比如六张卡片可能会整齐地分成两行,每行三张,但在更大的屏幕尺寸下可能出现一行四张、另一行两张的情况。

我们还是可以使用弹性布局,虽然不是最理想的解决方案,但胜在简单易用。对前面描述的这种问题,我们有两种选择:一是花时间计算多个断点,然后针对不同的弹性元素的宽度做特定设置;二是把这种问题看作是一种“效果还凑合”的回退行为,在支持grid的浏览器中使用网格布局来覆盖弹性布局。

图16.5 弹性布局使得最后一行中的卡片不会总是和上面每行的卡片宽度一致

[p404 图一]

下面我们来实现第二个选择。在弹性布局的后面,我们使用特性查询来检测是否支持grid并添加覆盖样式。更新下面的CSS代码到样式表中。

清单16.7 对支持网格布局的浏览器添加网格布局

[p404 代码清单一]

Fallback styles remain unchanged

回退样式不做更改

Queries for grid support within a media query block

在媒体查询块内部检测网格布局的支持情况

Defines column widths

定义列宽

Removes margins applied by the fallback layout

移除回退布局中设置的外边距

现在最新的浏览器中将会使用完美的布局方式。网格列会确保所有的网格元素宽度一致。使用repeat()auto-fit允许网格来确定当前的视口宽度下多少列最合适。这种解决方案在较老的浏览器中可以优雅地降级为弹性布局,在很小的视口中会显示更简单的移动布局。

16.2.2 为布局添加动画

页面的设计和布局工作已经完成,接下来该添加动画了。页面加载的时候,卡片是飞入的,就像图16.6展示的那样。卡片会以绕纵轴旋转90度的起始状态,从远处出现。然后它们会飞向观察者,在动画接近结束的时候,转到直接朝向观察者。图16.6展示了定义动画的三个关键帧。

这段动画包含两个变换,其中translateZ()使卡片从远处飞回来,rotateY()负责旋转卡片。清单16.8列出了相关代码,包括对flyin-grid容器设置了透视距离,定义了关键帧,并为每个flyin-grid元素添加了动画。我们也添加了不透明的设置,这样元素飞入的时候会附带着过渡特效。

清单16.8 添加飞入动画

[p405]

Sets a shared perspective on the container

在容器上设置共享的透视距离

�Applies animation to each item

为每个元素添加动画

Starts in the distance, rotated

以旋转后的状态,从远处开始

Much closer, but still mostly rotated

已经很近了,但几乎仍然是旋转状态

Finishes in normal position

以正常位置结束

图16.6 使用3D变换实现从远处飞入卡片

[p406 图一]

这段CSS在容器上设置了透视距离,这样所有的元素会处于相同的透视角度下。同时还为每个元素设置了动画。载入页面查看动画效果。

动画以旋转后的元素从远处飞回开始。在起始关键帧和中间关键帧之间,元素沿Z轴一路向前快速推进(从800px到160px),从透明逐渐过渡到完全不透明。从中间关键帧到最终关键帧,最后一小段推进结束,而大部分的旋转发生在这期间。

16.3 动画延迟和填充模式

可以使用animation-delay属性推迟动画开始的时间,行为和transition-delay类似。利用这个属性,我们可以设置动画交错发生,这和前一章中导航菜单交错产生过渡效果的方式差不多。通过为每个元素的动画略微错开长短不同的时间,可以使它们一个接一个地飞入,如图16.7所示。

图16.7 元素使用交错的动画效果飞入

[p407 图一]

下面的代码为四个网格元素添加延迟。但是,这段代码并没有完全按照我们预期的那样工作。先把代码添加到样式表中,然后我们研究一下问题所在以及如何处理它。

清单16.9 错开动画开始时间

[p407 代码清单一]

[p408 代码清单一]

Staggers the start of each item’s animation a little longer than the previous item

把每个元素的动画开始时间设置得比前一个稍晚一点

在浏览器中运行一下页面,你可能已经发现了问题。动画确实是在期望的时间播放的,但有些元素提前展示在了页面上,一小段时间之后它们消失然后播放动画(图16.8)。这有点不合理,不是我们想要的效果。我们希望所有的元素在开始的时候都是不可见的,只有在各自的动画执行的时候才会出现。

图16.8 后面的元素在动画还没开始播放的时候就出现在了最终位置

[p408 图一]

这个问题的出现是因为transformopacity属性只应用在了动画执行期间。动画开始之前,网格元素在页面上是可见的,就在它们各自的正常位置。动画开始的时候,它们瞬间变成0%关键帧上应用的属性值。我们需要把动画样式后向填充设置,就像一直暂停在第一帧,直到动画开始播放。可以使用animation-fill-mode属性来实现(图16.9)。

这里的深色盒子代表动画的持续时间。animation-fill-mode的默认值是none,意思是动画执行前或执行后动画样式都不会应用到元素上。如果设置animation-fill-mode: backwards,在动画执行之前,浏览器会取出动画中第一帧的值,并把它们应用在元素上;使用forwards会在动画播放完成之后仍然应用最后一帧的值;使用both将会同时向前和向后填充。

图16.9 使用animation-fill-mode可以在动画播放前或播放后应用动画样式

[p409 图一]

为页面添加后向填充模式可以修复动画开始时的元素跳动。更新下面代码到样式表中。

清单16.10 使用后向动画填充模式

[p409 代码清单一]

Applies first frame animation styles before animation begins

动画开始之前应用第一帧上的动画样式

这样就可以使动画的初始状态暂停在第一帧,等待动画的播放。现在,在动画开始之前,网格元素向后移动了800px,旋转了90度,opacity设为0,准备好了迎接动画开始。

因为动画结束时元素就停在它们本来的位置,我们不需要设置前向填充,卡片实际上已经完美地从动画的最后一帧变到了元素的静止位置。

16.4 通过动画传递意图

人们对动画有个误解,通常认为它们只是用来让页面变得有趣,没有什么实际的用处。有时候确实是这样(就像我们上一个例子),但不总是这样。有些非常好的动画不是最后才加上的,而是融入到了开发过程中。它们向用户传达页面上某些事物的特殊含义。

16.4.1 反馈用户操作

动画可以向用户表明按钮被点击了或者消息被接收了。如果你曾经提交过表单,回想一下是否经常记不清自己点没点过注册按钮,就知道这有多重要了。

在新页面上创建一个包含提交按钮的小表单。然后我们会再添加一个旋转指示器,让用户知道表单正在发送,浏览器正在等待服务器的响应。表单如图16.10所示,由一个标签、一个文本域和一个按钮组成。

图16.10 一个带保存按钮的简单的表单

[p410 图一]

新建一个页面和空白样式表,用来添加表单。先把下面清单中的HTML加进去。

清单16.11 包含保存按钮的表单

[p410 代码清单一]

Text area

文本域

Submit button

提交按钮

我们先添加一些CSS,让页面有合适的布局和样式。之后再加入一些有意义的动画效果来增强用户体验。把下面代码加入到样式表中。

清单16.12 调整表单布局并添加样式

[p410 代码清单二]

[p411 代码清单一]

Limits the width of the form

限制表单最大宽度

Blue button with white text

带白色文字的蓝色按钮

Darkens button for the hover state

鼠标悬浮时加深按钮颜色

我们假设这个表单是某个大型web应用中的一部分。用户点击保存按钮的时候,它会发送数据到服务器,或许还会在接收到响应之后添加一些新内容到页面上。但是网络连接需要时间。如果用户在等待响应的时候,可以有一些比较形象的指示告诉他们内容已经提交了,很快就会有反馈了,心里就会比较踏实。通常情况下会使用动画来提供这种指示。

我们可以修改保存按钮,增加一种“正在加载”的状态。这时候按钮文字隐藏起来,用一个旋转图标代替(图16.11)。用户提交表单的时候,我们使用JavaScript为按钮添加is-loading类,动画效果就出来了。

图16.11 用户点击保存的时候,旋转图标出现在按钮上

[p411 图一]

我们可以用多种不同的方式设计旋转图标。这里使用了我个人比较偏爱的一种设计,一个旋转的月牙形,看上去非常小但效果不错。添加旋转图标需要对CSS做两处改动,首先使用边框和边框圆角制作月牙形状,然后设置动画使其旋转起来。要使用这些样式,还需要少量的JavaScript语句,在按钮点击的时候添加is-loading类。

相关的CSS列在了下面的清单中。这段代码会在按钮上的一个绝对定位的伪元素上添加动画。把代码加入到样式表。

清单16.13 定义旋转动画和is-loading状态

[p412 代码清单一]

Hides the button text

隐藏按钮文字

Positions pseudo-element in the center of the button

把伪元素定位到按钮中心

Loops spin animation repeatedly

重复循环旋转动画

Defines one full rotation per iteration

设置每次循环都旋转一周

这样就为按钮定义了is-loading状态。一旦应用,按钮的文字被color: transparent设置成不可见,而伪元素通过绝对定位放在了按钮的中间。

这里的定位稍微有点麻烦。topleft属性分别把伪元素向下移动了按钮高度的一半、向右移动了按钮宽度的一半,这样伪元素的左上角恰好处于按钮的中心点。然后,负外边距又把伪元素分别向上和向左拉回了0.7em,而0.7em正好是按钮宽度和高度的一半。这四个属性作用在一起,使得伪元素在按钮的水平和竖直方向上都居中。可以为元素临时加上is-loading类,在浏览器的开发者工具中分别调整这些值,体会一下它们是如何使伪元素居中的。

明白伪元素定位之后,我们再来看动画。这里使用了一个新的关键字infinite赋值给动画重复次数,意思是只要is-loading类应用在按钮上,动画就一直重复。动画使用了旋转变换,从0度到360度,这样就可以把伪元素旋转一整圈。动画的结尾恰好使元素停留在开始的位置,在视觉上,动画每次重复都可以无缝衔接。

把下列清单中的script标签添加到网页。这样通过使用JavaScript的能力,当按钮被点击的时候,is-loading类就会添加。把代码放到</body>闭合标签前面。

清单16.14 按钮点击的时候添加is-loading

[p413 代码清单一]

Prevents form submission

阻止表单提交

Displays loading spinner

显示加载旋转图标

Code here would submit form data using JavaScript

这里的代码将会使用JavaScript提交表单数据

点击保存按钮的时候,preventDefault()阻止了默认的表单提交。这样在系统使用JavaScript提交表单数据的时候,可以让用户停留在当前页面,不会跳转离开。在此期间,输入功能是禁止的,is-loading类添加到了按钮上,旋转指示器会显示出来。加载页面并点击按钮,查看旋转指示器的展示效果。

这里我们没有真的提交表单数据,因为在这个demo中没有可提交数据的服务器。在真正开发应用的时候,一旦服务器返回响应,需要恢复表单可输入并移除is-loading类。我们这里只是为了演示,刷新页面就可以重置表单和移除is-loading类。

16.4.2 吸引用户注意力

动画也可以用来把用户的注意力吸引到某些地方。如果预测到用户可能会在文本域中输入较多的内容,我们可以提醒用户在输入的时候及时保存。使用动画快速摇动按钮,就可以提示用户保存他们输入的内容(图16.12)。

图16.12 快速左右移动按钮,产生摇晃效果

[p413 图一]

多次快速左右变换元素,就可以产生摇晃效果。我们可以定义一个关键帧动画,并使用shake类把动画应用到按钮元素上。添加下面代码到样式表。

清单16.15 定义摇晃动画

[p413 代码清单一]

[p414 代码清单一]

Uses the same keyframe definition at multiple points during the animation

动画执行期间,在多个位置使用相同的关键帧定义

Shifts the element left

向左移动元素

Shifts the element right

向右移动元素

Reduces the movement for the final shake

最后一次摇晃的时候减少移动幅度

我们在这个动画中增加了一些新的东西,即多次应用相同的关键帧定义。

在开始(0%)和结束(100%)关键帧,元素位于默认位置。因为这两个关键帧使用的值相同,我们可以只定义一次属性值,使用逗号分隔。10%、30%、50%和70%处的关键帧也一样,都是把元素向左移动,而20%、40%、和60%处的关键帧是把元素向右移动。80%和90%两个关键帧分别向右侧和左侧移动元素,但是幅度稍小。

动画一共摇动了四次元素,其中第四次幅度有所减小,用来模拟运动即将结束慢下来的过程。你也可以临时把shake类添加到按钮上,页面加载的时候直接查看动画效果。

注意

样式表中的动画可以多次重复调用,所以动画的定义不需要和最终使用动画的模块放在一起。我喜欢把所有@keyframe定义都聚集在一起,放在样式表接近结尾的地方。

最后,在我们认为用户可能需要保存输入的时候,使用JavaScript播放动画。可以使用keyup事件监听器和超时函数来实现。当用户向文本域输入字符的时候,我们可以设置一个一秒的超时函数,向按钮添加shake类。如果用户在一秒结束之前输入了其他字符,我们就清除计时,重新设置一个。按照下面清单更新页面里的script标签。

清单16.16 一秒延迟之后添加shake

[p415 代码清单一]

Defines a variable to refer to your timeout

定义一个变量,指向超时函数

Cancels the pending timeout (if present)

取消等待的超时函数(如果有的话)

Adds the shake class after a 1-second wait

1s等待之后,添加shake类

Removes the shake class after the animation ends

动画结束之后移除shake类

现在加载页面并在文本域中输入一些文字。等待一秒之后,保存按钮会出现摇晃。如果我们持续输入,计时器会不断地重置,摇晃动画不会出现,直到下一次停止输入超过一秒之后。这样摇晃的按钮不会总是打断用户,只在用户停下来的时候才会触发。

我们也用到了JavaScript的animationend事件。摇晃动画播放结束的时候才会触发这个事件。事件触发之后,shake类会从按钮上移除,这样会在用户下次输入并停下来的时候重新添加shake类,并再次播放动画。

像这样使用JavaScript添加和移除类可能是最简单的操作动画的方式。但如果你特别熟悉这门语言,还有一整套处理CSS动画的API,其中包含暂停、取消和逆向播放动画的能力。要想了解更多信息,可以查看MDN的文档https://developer.mozilla.org/en-US/docs/Web/API/Animation

不论加载指示器还是摇晃的保存按钮,这些动画都向用户传达了很多信息,而且不需要用户阅读任何说明。它们都一目了然地表达了各自的含义,使用的UI也不显得突兀。

我们在开发web应用的时候,应该经常思考是否可以使用动画向用户提供有价值的反馈,即使是非常小的动画。可能是在发送邮件的时候,文本区域飞出屏幕边缘;或者删除草稿的时候,使用动画让草稿缩小直至消失。动画不需要多么显眼或者炫酷,只需要对用户产生回应,让他们知道自己的操作是在按预期进行。

可以考虑使用预定义关键帧动画集,推荐一款优秀的产品http://animista.net/。它提供了非常大的动画库可供选择,包含像果冻一样的弹跳、滚动和摇晃等效果。

16.5 最后一点建议

对很多web开发者来讲,CSS是一种让人望而生畏的语言。它一脚植根于设计领域,另一脚又踩进了代码世界。CSS语言中有些内容不是很直观,特别是对于那些自学的开发者。我希望本书可以帮你找到一些门道。

我们已经深入学习了这门语言中最基础的部分,也学习了一些页面布局中容易产生疑惑的内容。其中涵盖了很多主题,从如何组织CSS使代码易于维护,到最新的布局方式。我们还尝试进入设计领域,创建了实用且生动美观的界面。

我最后再给你一条建议,就是保持好奇心。我们已经向你介绍了CSS工具集里的一大批工具,但这些工具可以组合和匹配的方式却是无穷无尽的。当你看到令人赞叹的web页面的时候,打开浏览器的开发者工具,试着去弄清楚它是如何实现的。多多在线关注那些制作创意demo或者提供趣味教程的开发者和设计师,多多尝试新事物,持续学习。

总结

  • 使用关键帧动画定义动画中的关键点
  • 使用前向和后向填充模式使动画的开始或结束无缝衔接
  • 在恰当的时机使用JavaScript触发动画
  • 为web页面添加动画,不求华丽炫酷,只需针对用户交互传达正确的含义