--- title: animation slug: Web/CSS/animation tags: - CSS - CSS Animations - CSS Property - CSS3 动画 - Reference translation_of: Web/CSS/animation ---
CSS animation 属性是 {{cssxref("animation-name")}},{{cssxref("animation-duration")}}, {{cssxref("animation-timing-function")}},{{cssxref("animation-delay")}},{{cssxref("animation-iteration-count")}},{{cssxref("animation-direction")}},{{cssxref("animation-fill-mode")}} 和 {{cssxref("animation-play-state")}} 属性的一个简写属性形式。
{{EmbedInteractiveExample("pages/css/animation.html")}}
/* @keyframes duration | timing-function | delay | iteration-count | direction | fill-mode | play-state | name */ animation: 3s ease-in 1s 2 reverse both paused slidein; /* @keyframes duration | timing-function | delay | name */ animation: 3s linear 1s slidein; /* @keyframes duration | name */ animation: 3s slidein;
<div class="grid">
<div class="col">
<div class="note">
Given the following animation:
<pre>@keyframes slidein {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}</pre>
</div>
<div class="row">
<div class="cell">
<button class="play" title="PLAY"></button>
</div>
<div class="cell flx">
<div class="overlay">animation: 3s ease-in 1s 2 reverse both paused slidein;</div>
<div class="animation a1"></div>
</div>
</div>
<div class="row">
<div class="cell">
<button class="pause" title="PAUSE"></button>
</div>
<div class="cell flx">
<div class="overlay">animation: 3s linear 1s slidein;</div>
<div class="animation a2"></div>
</div>
</div>
<div class="row">
<div class="cell">
<button class="pause" title="PAUSE"></button>
</div>
<div class="cell flx">
<div class="overlay">animation: 3s slidein;</div>
<div class="animation a3"></div>
</div>
</div>
</div>
</div>
html,body {
height: 100%;
box-sizing: border-box;
}
pre { margin-bottom: 0; }
svg { width: 1.5em; height: 1.5em; }
button {
width: 27px;
height: 27px;
background-size: 16px;
background-position: center;
background-repeat: no-repeat;
border-radius: 3px;
cursor: pointer;
}
button.play {
background-image: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cstyle%3Epath%20%7Bdisplay%3Anone%7D%20path%3Atarget%7Bdisplay%3Ablock%7D%3C%2Fstyle%3E%3Cpath%20id%3D%22play%22%20d%3D%22M3%2C3%20L3%2C13%20L13%2C8%20Z%22%20%2F%3E%3Cpath%20id%3D%22pause%22%20d%3D%22M5%2C4%20L7%2C4%20L7%2C13%20L5%2C13%20Z%20M9%2C4%20L11%2C4%20L11%2C13%20L9%2C13%20Z%22%20%2F%3E%3Cpath%20id%3D%22restart%22%20d%3D%22M13%2C9%20A5%2C5%2C1%2C1%2C1%2C8%2C4%20L8%2C2%20L12%2C5%20L8%2C8%20L8%2C6%20A3%2C3%2C1%2C1%2C0%2C11%2C9%20A1%2C1%2C1%2C1%2C1%2C13%2C9%20z%22%20%2F%3E%3C%2Fsvg%3E#play');
}
button.pause {
background-image: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cstyle%3Epath%20%7Bdisplay%3Anone%7D%20path%3Atarget%7Bdisplay%3Ablock%7D%3C%2Fstyle%3E%3Cpath%20id%3D%22play%22%20d%3D%22M3%2C3%20L3%2C13%20L13%2C8%20Z%22%20%2F%3E%3Cpath%20id%3D%22pause%22%20d%3D%22M5%2C4%20L7%2C4%20L7%2C13%20L5%2C13%20Z%20M9%2C4%20L11%2C4%20L11%2C13%20L9%2C13%20Z%22%20%2F%3E%3Cpath%20id%3D%22restart%22%20d%3D%22M13%2C9%20A5%2C5%2C1%2C1%2C1%2C8%2C4%20L8%2C2%20L12%2C5%20L8%2C8%20L8%2C6%20A3%2C3%2C1%2C1%2C0%2C11%2C9%20A1%2C1%2C1%2C1%2C1%2C13%2C9%20z%22%20%2F%3E%3C%2Fsvg%3E#pause');
}
button.restart {
background-image: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cstyle%3Epath%20%7Bdisplay%3Anone%7D%20path%3Atarget%7Bdisplay%3Ablock%7D%3C%2Fstyle%3E%3Cpath%20id%3D%22play%22%20d%3D%22M3%2C3%20L3%2C13%20L13%2C8%20Z%22%20%2F%3E%3Cpath%20id%3D%22pause%22%20d%3D%22M5%2C4%20L7%2C4%20L7%2C13%20L5%2C13%20Z%20M9%2C4%20L11%2C4%20L11%2C13%20L9%2C13%20Z%22%20%2F%3E%3Cpath%20id%3D%22restart%22%20d%3D%22M13%2C9%20A5%2C5%2C1%2C1%2C1%2C8%2C4%20L8%2C2%20L12%2C5%20L8%2C8%20L8%2C6%20A3%2C3%2C1%2C1%2C0%2C11%2C9%20A1%2C1%2C1%2C1%2C1%2C13%2C9%20z%22%20%2F%3E%3C%2Fsvg%3E#restart');
}
.grid {
width: 100%;
height: 100%;
display: flex;
background: #EEE;
font: 1em monospace;
}
.row {
display: flex;
flex: 1 auto;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
}
.col {
display: flex;
flex: 1 auto;
flex-direction: column;
}
.cell {
box-sizing: border-box;
margin: .5em;
padding: 0;
background-color: #FFF;
overflow: hidden;
text-align: left;
}
.flx {
flex: 1 0;
}
.note {
background: #fff3d4;
padding: 1em;
margin: .5em;
font: .8em sans-serif;
text-align: left;
flex: none;
}
.overlay { padding: .5em; }
@keyframes slidein {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
.a1 { animation: 3s ease-in 1s 2 reverse both paused slidein; }
.a2 { animation: 3s linear 1s slidein; }
.a3 { animation: 3s slidein; }
.animation {
background: #3F87A6;
width: 100%;
height: calc(100% - 1.5em);
transform-origin: left center;
}
window.addEventListener('load', function () {
var ANIMATION = Array.from(document.querySelectorAll('.animation'));
var BUTTON = Array.from(document.querySelectorAll('button'));
function toggleButton (btn, type) {
btn.classList.remove('play', 'pause', 'restart');
btn.classList.add(type);
btn.title = type.toUpperCase(type);
}
function playPause (i) {
var btn = BUTTON[i];
var anim = ANIMATION[i];
if (btn.classList.contains('play')) {
anim.style.animationPlayState = 'running';
toggleButton(btn, 'pause');
} else if (btn.classList.contains('pause')) {
anim.style.animationPlayState = 'paused';
toggleButton(btn, 'play');
} else {
anim.classList.remove('a' + (i + 1));
setTimeout(function () {
toggleButton(btn, i === 0 ? 'play' : 'pause');
anim.style.animationPlayState = '';
anim.classList.add('a' + (i + 1));
}, 100)
}
}
ANIMATION.forEach(function (node, index) {
node.addEventListener('animationstart', function () { toggleButton(BUTTON[index], 'pause'); });
node.addEventListener('animationend', function () { toggleButton(BUTTON[index], 'restart'); });
});
BUTTON.forEach(function (btn, index) {
btn.addEventListener('click', function () { playPause(index); });
});
})
{{EmbedLiveSample("animation", "100%", 260, "", "", "example-outcome-frame")}}
哪些属性是可动画的?值得注意的是,此描述也适用于CSS变换。
{{cssinfo}}
animation 属性用来指定一组或多组动画,每组之间用逗号相隔。
每组动画规定的属性如下:
每个动画定义中的属性值的顺序很重要:可以被解析为 {{cssxref("<time>")}} 的第一个值被分配给{{cssxref("animation-duration")}}, 第二个分配给 {{cssxref("animation-delay")}}。
每个动画定义中的值的顺序,对于区分 {{cssxref("animation-name")}} 值与其他关键字也很重要。解析时,对于除 {{cssxref("animation-name")}} 之外的有效的关键字,必须被前面的简写中没有找到值的属性所接受。此外,在序列化时,{{cssxref("animation-name")}} 与以及其他属性值做区分等情况下,必须输出其他属性的默认值。
<single-animation-iteration-count><single-animation-direction><single-animation-fill-mode><single-animation-play-state><div class="view_port">
<div class="polling_message">
Listening for dispatches
</div>
<div class="cylon_eye"></div>
</div>
.polling_message {
color: white;
float: left;
margin-right: 2%;
}
.view_port {
background-color: black;
height: 25px;
width: 100%;
overflow: hidden;
}
.cylon_eye {
background-color: red;
background-image: linear-gradient(to right,
rgba(0, 0, 0, .9) 25%,
rgba(0, 0, 0, .1) 50%,
rgba(0, 0, 0, .9) 75%);
color: white;
height: 100%;
width: 20%;
-webkit-animation: 4s linear 0s infinite alternate move_eye;
animation: 4s linear 0s infinite alternate move_eye;
}
@-webkit-keyframes move_eye { from { margin-left: -20%; } to { margin-left: 100%; } }
@keyframes move_eye { from { margin-left: -20%; } to { margin-left: 100%; } }
{{EmbedLiveSample('Cylon_Eye')}}
更多示例请参阅使用CSS动画。
眨眼和闪烁的动画对于有认知问题的人来说是有问题的,比如注意力缺陷多动障碍(ADHD)。此外,某些动画效果可以触发前庭神经紊乱、癫痫、偏头痛和暗点敏感性。
考虑提供一种暂停或禁用动画的机制,以及使用 Reduced Motion Media Query(简约运动媒体查询),为那些表示不喜欢动画的用户创建一个良好的体验。
| Specification | Status | Comment |
|---|---|---|
| {{SpecName('CSS3 Animations', '#animation', 'animation')}} | {{Spec2('CSS3 Animations')}} | Initial definition |
{{Compat("css.properties.animation")}}