.t_article {
letter-spacing: 1px;
color: #051b05;
}
.t_article h1 {
font-size: 1.6em !important;
margin-top: 12px !important;
margin-bottom: 12px !important;
}
.t_article h2 {
font-size: 1.32em !important;
margin-top: 12px !important;
margin-bottom: 12px !important;
}
.t_article h1, .t_article h2, .t_article h3 {
text-shadow: 0px 0px 2px rgba(0,27,0,.3);
}
.t_article p {
margin-top: 3px;
margin-bottom: 0px;
}
.t_article p:last-child {
margin-bottom: 3px;
}
.t_code {
border-left: 6px solid #aac931;
margin: 12px 0px;
}
.t_code div {
border-bottom: 1px dashed #aac931;
padding-left: 12px;
}
.t_instance {
margin: 12px auto 12px auto;
width: 240px;
height: 60px;
background-color: #ffc20a;
text-align: center;
padding-top: 30px;
}
.t_instance_1 {
background-color: #f1f1f1;
color: black;
}
.t_instance_1:hover {
background-color: #5b9bd1;
color: white;
}
.t_transition {
background-color: #f1f1f1;
color: black;
transition-property: background-color, color;
transition-duration: 2s;
}
.t_transition:hover {
background-color: #5b9bd1;
color: white;
}
.t_table_property {
margin-left: 2em;
margin-top: 12px;
margin-bottom: 12px;
border-spacing: 0px;
}
.t_table_property tr td {
border-bottom: 1px dashed #aac931;
padding-left: 1em;
padding-right: 1em;
padding-top: 3px;
padding-bottom: 3px;
}
.t_table_property tr td:first-child {
border-right: 1px dashed #aac931;
}
.t_table_property tr:first-child td {
border-top: 2px solid #aac931;
}
.t_table_property tr:last-child td {
border-bottom: 2px solid #aac931;
}
.t_table_property tr td:first-child {
font-weight: bold;
}
@keyframes wobble {
0% {
left: 100px;
}
40% {
left: 150px;
}
60% {
left: 75px;
}
100% {
left: 100px;
}
}
.t_keyframe {
animation: wobble 5s infinite;
position: relative;
left: 100px;
}
@keyframes bounce {
from {
top: 100px;
animation-timing-function: ease-out;
}
25% {
top: 50px;
animation-timing-function: ease-in;
}
50% {
top: 100px;
animation-timing-function: ease-out;
}
75% {
top: 75px;
animation-timing-function: ease-in;
}
to {
top: 100px;
}
}
.t_time_function {
animation: bounce 5s infinite;
position: relative;
top: 100px;
}
@keyframes transform {
from {
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
to {
transform: rotate(360deg);
}
}
.t_transform {
width: 240px;
height: 240px;
margin: 0 auto;
border-radius: 50%;
background: linear-gradient(#ffc20a 80%, #aac931 0);
background-size: 100% 20px;
animation: transform 30s infinite;
}
CSS的过渡提供了动态改变CSS属性值的方法,但在动画的进程上过渡仅提供了很少的控制给使用者。
使用动画,使用者可以通过设定一套keyframe来很好的控制动画的进程。动画改变CSS属性的值的方式和过渡是类似的,两者间根本的差别是过渡是当属性值发生变化时触发执行,而动画则是当动画属性被应用时促发执行。因此,动画需要指定动画效果,在keyframe中指定。
CSS动画
CSS动画会影响属性的值,在动画期间,属性值将由动画来控制,动画计算的值将覆盖所有除了使用!important标签之外的所有属性值。
如果在同一时间有多个动画作用在一个属性上,最后指定的动画生效。
动画应用之前、动画的延迟时间到达之前和动画结束之后都不会影响属性的值。
上图展示了属性值是如何被计算的,原生的style(intrinsic style)被展示在图的上面,在动画没有运行或处于延迟时,原生的style被使用,在动画期间,使用动画计算的属性值。
在指定动画的样式被解析完成后,并且文档的加载事件通告后,动画才开始执行。因此,指定在文档样式表中的动画将在文档加载后开始,而在文档后通过修改样式指定的动画将在样式被解析后开始,例如:hover等操作。
动画一旦开始,它将一直运行直到结束,或者动画被移除,在动画运行期间改变动画的属性将没有效果。如果你想要重启一个动画,需要移除它,再重新加载它。
设置属性display到none将终止任何运行中的动画,如果一个元素的display属性为none,更新该属性到非none的值将触发所有动画。
动画帧
动画帧用于指定动画在各个点的动态属性。在CSS中,使用@keyframes指定动画一个周期的行为,@keyframes规则的定义方式如下:
@keyframes mymove {
from {top:0px;}
to {top:200px;}
}
@keyframes是关键字,mymove指定了动画的名称,下面是定义了选择器。选择器定义了动画执行的过程,可以通过百分比来指定,或者使用关键字"from"和"to","from"相当于0%,而"to"相当于100%。上面的例子演示了使用"from"和"to",下面是使用百分比的场景:
@keyframes wobble {
0% {
left: 100px;
}
40% {
left: 150px;
}
60% {
left: 75px;
}
100% {
left: 100px;
}
}
注意指定百分比一定要带上"%",否则无效。
如果"0%"或者"from"未指定,那么用户代理会构造一个"0%",使用动画启动时动态计算的值。如果"100%"或者"to"未指定,那么用户代理构造一个"100%",使用属性动态计算的值。如果负的百分比值或者大于100%的值被指定,该值将被忽略。
选择器的定义块由属性和值组成,不能使用动画的属性将被忽略。另外,带有!important的属性被忽略。
配置的@keyframes规则将被排序,如果存在重复,则最后一个生效,并且@keyframes规则不是层叠的,因此,一个动画仅会对应到一个@keyframes规则。
为了确定一组动画帧,选择器的所有值被按照时间递增排序,如果存在重复,那么最后定义的帧将被用于提供那个时间点的信息。
如果一个属性没有在某个动画帧中指定,或者指定的是无效的,那么动画的进程会忽略该动画帧。一个帧可以指定多个属性,但每个属性的动画是独立进行的。
回到上面wobble的例子,四个动画帧被指定。在第一个帧中,‘left‘属性的值为100px,到了40%,‘left‘被演变到150px,在60%时,‘left‘演变为75px,在动画的结尾,‘left‘为100px。下面是该动画的实际运行效果:
时间函数
一个动画帧还可以指定时间函数,用于描述动画如何移动到下一个动画帧。时间函数的说明请看过渡的时间函数。下面是在动画中使用时间函数的一个例子:
@keyframes bounce {
from {
top: 100px;
animation-timing-function: ease-out;
}
25% {
top: 50px;
animation-timing-function: ease-in;
}
50% {
top: 100px;
animation-timing-function: ease-out;
}
75% {
top: 75px;
animation-timing-function: ease-in;
}
to {
top: 100px;
}
指定在‘to‘或者100%动画帧的时间函数将被忽略。
animation-name属性
animation-name属性定义了一个被应用的动画名称列表。如果定义的名称不匹配任何动画,动画将不执行。而且,如果动画名称是‘none‘,即为没有动画,这能被用于覆盖先前的动画设置。如果多个动画尝试修改同一个属性,列表最后的动画被采用。
由于动画名称是一个列表,如果该列表的长度和其他属性(下面介绍)列表的长度不等,那么将以动画名称列表为准,超出动画名称列表长度的属性被忽略,如果长度不足,则重复使用属性的值直到满足动画名称列表的长度。
animation-name: <single-animation-name> [ ‘,’ <single-animation-name> ]*
初始值:none
animation-duration属性
animation-duration属性定义了动画的时间长度,单位秒。
animation-duration: <time> [, <time>]*
初始值:0s
初始值"0s"意味着动画不花费时间,这时animation-fill-mode任然会被应用,在这种情况下,动画在延迟时间段将展示0%动画帧的值,延迟结束后,将直接展示100%动画帧的值。负值将被认为不合法。
animation-timing-function属性
指定动画的时间函数,看‘transition-timing-function属性‘。
animation-timing-function: <single-timing-function> [ ‘,’ <single-timing-function> ]*
初始值: ease
所有有效的时间函数都在‘transition-timing-function‘中定义。
对于一个动画,时间函数在两个动画帧之间应用,不会覆盖整个动画。
animation-iteration-count属性
animation-iteration-count属性指定动画被运行的次数。初始值是1,及动画仅被执行1次;值‘infinite‘表示动画一直反复执行;非整数的数字将导致动画运行到中间部分;负值是无效的。这个属性经常和animation-direction属性的‘alternate‘值一起使用(下面介绍)。
animation-iteration-count: <single-animation-iteration-count> [ ‘,’ <single-animation-iteration-count> ]*
初始值:1
animation-direction属性
animation-direction属性定义动画是否应该反向运行,当动画反向运行时,时间函数也会反向。例如,当反向运行ease-in动画时将出现ease-out的效果。
animation-direction: <single-animation-direction> [ ‘,’ <single-animation-direction> ]*
初始值:normal
支持的属性值包括:
normal | 动画按照指定的方式运行 |
reverse | 动画按照指定的方向反向运行 |
alternate | 动画在奇数次运行时正向运行,在偶数次运行时反向运行 |
alternate-reverse | 动画在奇数次运行时反向运行,在偶数次运行时正向运行 |
animation-play-state属性
animation-play-state属性定义了动画是运行还是停止。一个运行的动画能通过设置该属性为‘paused‘来停止它。为了继续运行该动画,你需要重新设置该属性到‘running‘。一个停止的动画将继续展示展示动画的当前值,当停止的动画被恢复时,它从当前值重启,而不是从动画的开始。
animation-play-state: <single-animation-play-state> [ ‘,’ <single-animation-play-state> ]*
初始值:running
animation-delay属性
animation-delay属性定义了动画什么时候开始。animation-delay属性值为0s意味着动画应用后立即执行;否则,动画被应用后将延迟指定的时间后执行。
如果指定了一个负数给属性,那么动画将在被应用后立即执行,但是会从指定的负偏移处开始执行(从动画的中间执行)。
animation-delay: <time> [, <time>]*
初始值:running
animation-fill-mode属性
animation-fill-mode属性定义在动画执行的时间之外,什么值被应用。默认,一个动画将不影响它被应用的时间(animation-name属性被设置到元素)和他被执行的时间(由animation-delay属性确定)期间的属性值;同样,默认情况下,动画不影响他执行结束后(由animation-duration属性决定)的属性值。animation-fill-mode属性能够重新指定这些行为。
如果animation-fill-mode的值是‘backwards‘,在animation-delay定义的延迟期间,动画将设置属性值为第一个动画帧的属性值,这个值可能是‘from‘动画帧的值(当animation-direction被设置为normal或者alternate),也可能是‘to‘动画帧的值(当animation-direction被设置为reverse或者alternate-reverse)。
如果animation-fill-mode属性值为‘forwards‘,那么动画结束后(由animation-iteration-count属性确定),动画将设置属性值为动画结束时的属性值。当animation-iteration-count为大于0的整数时,那么值为动画完成后的值;当animation-iteration-count为0,值为动画开始时的值。
如果animation-fill-mode属性值为‘both‘,那么动画将同时应用‘backwards‘和‘forwards‘的规则。
animation-fill-mode: <single-animation-fill-mode> [ ‘,’ <single-animation-fill-mode> ]*
初始值:none
animation简写属性
animation简写属性就是一个逗号分隔的动画定义列表。
animation: <single-animation> [ ‘,’ <single-animation> ]*
<single-animation> = <single-animation-name> || <time> || <single-animation-timing-function> || <time> || <single-animation-iteration-count> || <single-animation-direction> || <single-animation-fill-mode> || <single-animation-play-state>
注意单个动画定义的顺序是很重要的:第一个定义的时间<time>被作为animation-duration,第二个定义的时间<time>作为animation-delay。
JavaScript事件
在一个动画的生命周期中,CSS动画定义了3种JavaScript事件:
- animationstart
- 出现在动画的开始,如果设置了动画延迟时间,那么事件将在延迟时间到达后通知。一个负的延迟时间将导致事件在等待延迟时间的绝对值时间后通知。
- animationend
- 事件完成后通知。
- animationiteration
- 出现在每个动画迭代结束时,但如果出现animationend事件,则animationiteration事件不再通知,这意味着如果动画的迭代少于一次,则不会出现该事件。
你能像监听其它JavaScript事件一样监听动画事件,下面是一个例子:
element.addEventListener(
"animationstart",
function () { window.alert("Animation started!") }
);
实例
@keyframes transform {
from {
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
to {
transform: rotate(360deg);
}
}
animation: transform 30s infinite;