Usando animações CSS

  • Revision slug: CSS/Using_CSS_animations
  • Revision title: Usando animações CSS
  • Revision id: 292936
  • Criado:
  • Criador: francisco.hansen
  • É a revisão atual? Não
  • Comentar

Conteúdo da revisão

Animações CSS3 tornam possivel animar transições de um estilo CSS para outro. Animações se consistem de dois componentes: um estilo descrevendo a animação e um set de keyframes que indicam o estado final e inicial do estilo CSS da animação, bem como possíveis waypoints intermediários ao longo do caminho.

Existem três vantagens chave para animações CSS além das técnicas tradicionais de animação dirigidas por script:

  1. São de fácil utilização para animações simples; você pode criá-las sem mesmo ter que conhecer JavaScript.
  2. As animações executam bem, mesmo sobre moderada carga do sistema. Animações simples podem normalmente ser executadas precariamente em JavaScript (a não ser que sejam bem feitas). A ferramenta de renderização pode usar frame-skipping e outras técnicas para manter a performance o mais estável possível.
  3. Deixando o navegador controlar a sequência de animação permite ao navegador otimizar a performance e eficiência em, por exemplo, reduzir a frequência de update de animações correndo em abas que não estão visíveis no momento.

Configurando a animação

Para criar uma sequência de animação CSS, você estiliza o elemento que deseja animar com a propriedade {{ cssxref("animation") }} ou suas sub-propriedades. Isso permite que você configure a sincronização da animação, bem como outros detalhes de como a de como a sequência de animação deveria progredir. Isso não configura a aparência atual da animação, que é feita usando a regra com parênteses (at-rule) {{ cssxref("@keyframes") }} como descrito em {{ anch("Defining the animation sequence using keyframes") }} abaixo.

 As sub-propriedades da propriedade {{ cssxref("animation") }} são:

{{ cssxref("animation-delay") }}
Configura o delay entre o tempo em que o elemento é carregado e o inicio da sequência de animação.
{{ cssxref("animation-direction") }}
Configura se a animação deve ou nao alternar a direção em cada execução durante a sequência ou voltar ao ponto inicial e se repetir.
{{ cssxref("animation-duration") }}
Configura o tempo que uma animação deveria levar para complear um ciclo.
{{ cssxref("animation-iteration-count") }}
Configura o numero de vezes que uma animação deveria se repetir; você pode especificar infinito para repetir a animação indefinidamente.
{{ cssxref("animation-name") }}
Especifica o nome da regra com parênteses (at-rule) {{ cssxref("@keyframes") }} at-rule descrevendo os keyframes da animação.
{{ cssxref("animation-play-state") }}
Permite voce pausar e resumir a sequência da animação.
{{ cssxref("animation-timing-function") }}
Configura a sincronização da animação; que é, como a animação transita por keyframes, por estabilizar curvas de aceleração.
{{ cssxref("animation-fill-mode") }}
Configura que valores são aplicados pela animação antes e depois de se executar.

Definindo a sequência de animação usando keyframes

Uma vez que você configurou a sincronização da animação, voce precisa definir a aparência da animação. Isso é feito por estabelecer duas ou mais keyframes usando a regra com parênteses (at-rule) {{ cssxref("@keyframes") }}. Cada keyframe descreve como o elemento animado deveria se renderizar a um tempo dado durante a sequência de animação.

Since the timing of the animation is defined in the CSS style that configures the animation, keyframes use a {{ cssxref("percentage") }} to indicate the time during the animation sequence at which they take place. 0% indicates the first moment of the animation sequence, while 100% indicates the final state of the animation. These two times must be specified so that the browser knows where the animation should start and finish; because they're so important, these two times have special aliases: from and to.

You can optionally include additional keyframes that describe intermediate steps along the way from the starting point to the ending point of the animation.

Examples

Note: The examples here use don't use any prefix on the animation CSS properties. Older browsers may need prefixes; the live examples you can click to see in your browser also include the -webkit prefixed versions.

Making text slide across the browser window

This simple example styles the {{ HTMLElement("h1") }} element so that the text slides in from off the right edge of the browser window.

h1 {
  animation-duration: 3s;
  animation-name: slidein;
}

@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}

The style for the {{ HTMLElement("h1") }} element here specifies that the animation should take 3 seconds to execute from start to finish, using the {{ cssxref("animation-duration") }} property, and that the name of the {{ cssxref("@keyframes") }} at-rule defining the keyframes for the animation sequence is named "slidein".

If we wanted any custom styling on the {{ HTMLElement("h1") }} element to appear in browsers that don't support CSS animations, we would include it here as well; however, in this case we don't want any custom styling other than the animation effect.

The keyframes are defined using the {{ cssxref("@keyframes") }} at-rule. In this case, we have just two keyframes. The first occurs at 0% (using the alias from). Here, we configure the left margin of the element to be at 100% (that is, at the far right edge of the containing element), and the width of the element to be 300% (or three times the width of the containing element). This causes the first frame of the animation to have the header drawn off the right edge of the browser window.

The second (and final) keyframe occurs at 100% (using the alias to). The left margin is set to 0% and the width of the element is set to 100%. This causes the header to finish its animation flush against the left edge of the content area.

{{ CSSLiveSample("animations/cssanim1.html") }}

Adding another keyframe

Let's add another keyframe to the previous example's animation. Let's say we want the header's font size to increase as it moves from right to left for a while, then to decrease back to its original size. That's as simple as adding this keyframe:

75% {
  font-size: 300%;
  margin-left: 25%;
  width: 150%;
}

This tells the browser that 75% of the way through the animation sequence, the header should have its left margin at 25% and the width should be 150%.

{{ CSSLiveSample("animations/cssanim2.html") }}

Making it repeat

To make the animation repeat itself, simply use the {{ cssxref("animation-iteration-count") }} property to indicate how many times to repeat the animation. In this case, let's use infinite to have the animation repeat indefinitely:

h1 {
  animation-duration: 3s;
  animation-name: slidein;
  animation-iteration-count: infinite;
}

{{ CSSLiveSample("animations/cssanim3.html") }}

Making it move back and forth

That made it repeat, but it's very odd having it jump back to the start each time it begins animating. What we really want is for it to move back and forth across the screen. That's easily accomplished by setting {{ cssxref("animation-direction") }} to alternate:

h1 {
  animation-duration: 3s;
  animation-name: slidein;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}

{{ CSSLiveSample("animations/cssanim4.html") }}

Using animation events

You can get additional control over animations -- as well as useful information about them -- by making use of animation events. These events, represented by the {{ domxref("event/AnimationEvent", "AnimationEvent") }} object, can be used to detect when animations start, finish, and begin a new iteration. Each event includes the time at which it occurred as well as the name of the animation that triggered the event.

We'll modify the sliding text example to output some information about each animation event when it occurs, so we can get a look at how they work.

Adding the animation event listeners

We'll use JavaScript code to listen for all three possible animation events. The setup() function configures our event listeners; we call it when the document is first loaded in order to set things up.

function setup() {
  var e = document.getElementById("watchme");
  e.addEventListener("animationstart", listener, false);
  e.addEventListener("animationend", listener, false);
  e.addEventListener("animationiteration", listener, false);
  
  var e = document.getElementById("watchme");
  e.className = "slidein";
}

This is pretty standard code; you can get details on how it works in the documentation for {{ domxref("element.addEventListener()") }}. The last thing the setup() function here does is set the class on the element we'll be animating to "slidein"; we do this to start the animation.

Why? Because the animationstart event fires as soon as the animation starts, and in our case, that happens before our code runs. So we'll start the animation ourselves by setting the class of the element to the style that gets animated after the fact.

Receiving the events

The events get delivered to the listener() function, which is shown below.

function listener(e) {
  var l = document.createElement("li");
  switch(e.type) {
    case "animationstart":
      l.innerHTML = "Started: elapsed time is " + e.elapsedTime;
      break;
    case "animationend":
      l.innerHTML = "Ended: elapsed time is " + e.elapsedTime;
      break;
    case "animationiteration":
      l.innerHTML = "New loop started at time " + e.elapsedTime;
      break;
  }
  document.getElementById("output").appendChild(l);
}

This code, too, is very simple. It simply looks at the {{ domxref("event.type") }} to determine which kind of animation event occurred, then adds an appropriate note the {{ HTMLElement("ul") }} (unordered list) we're using to log these events.

The output, when all is said and done, looks something like this:

  • Started: elapsed time is 0
  • New loop started at time 3.01200008392334
  • New loop started at time 6.00600004196167
  • Ended: elapsed time is 9.234000205993652

Note that the times are very close to, but not exactly, those expected given the timing established when the animation was configured. Note also that after the final iteration of the animation, the animationiteration event isn't sent; instead, the animationend event is sent.

The HTML

Just for the sake of completeness, here's the HTML that displays the page content, including the list into which the script inserts information about the received events:

<body onload="setup()">
  <h1 id="watchme">Watch me move</h1>
  <p>This example shows how to use CSS animations to make <code>H1</code> elements
  move across the page.</p>
  <p>In addition, we output some text each time an animation event fires, so you can see them in action.</p>
  <ul id="output">
  </ul>
</body>

{{ CSSLiveSample("animations/animevents.html") }}

See also

Fonte da revisão

<p>Animações CSS3 tornam possivel animar transições de um estilo CSS para outro. Animações se consistem de dois componentes: um estilo descrevendo a animação e um set de keyframes que indicam o estado final e inicial do estilo CSS da animação, bem como possíveis waypoints intermediários ao longo do caminho.</p>
<p>Existem três vantagens chave para animações CSS além das técnicas tradicionais de animação dirigidas por script:</p>
<ol>
  <li>São de fácil utilização para animações simples; você pode criá-las sem mesmo ter que conhecer JavaScript.</li>
  <li>As animações executam bem, mesmo sobre moderada carga do sistema. Animações simples podem normalmente ser executadas precariamente em JavaScript (a não ser que sejam bem feitas). A ferramenta de renderização pode usar frame-skipping e outras técnicas para manter a performance o mais estável possível.</li>
  <li>Deixando o navegador controlar a sequência de animação permite ao navegador otimizar a performance e eficiência em, por exemplo, reduzir a frequência de update de animações correndo em abas que não estão visíveis no momento.</li>
</ol>
<h2 id="Configurando_a_anima.C3.A7.C3.A3o">Configurando a animação</h2>
<p>Para criar uma sequência de animação CSS, você estiliza o elemento que deseja animar com a propriedade {{ cssxref("animation") }} ou suas sub-propriedades. Isso permite que você configure a sincronização da animação, bem como outros detalhes de como a de como a sequência de animação deveria progredir. Isso <strong>não</strong> configura a aparência atual da animação, que é feita usando a regra com parênteses (at-rule) {{ cssxref("@keyframes") }} como descrito em {{ anch("Defining the animation sequence using keyframes") }} abaixo.</p>
<p>&nbsp;As sub-propriedades da propriedade {{ cssxref("animation") }} são:</p>
<dl>
  <dt>
    {{ cssxref("animation-delay") }}</dt>
  <dd>
    Configura o delay entre o tempo em que o elemento é carregado e o inicio da sequência de animação.</dd>
  <dt>
    {{ cssxref("animation-direction") }}</dt>
  <dd>
    Configura se a animação deve ou nao alternar a direção em cada execução durante a sequência ou voltar ao ponto inicial e se repetir.</dd>
  <dt>
    {{ cssxref("animation-duration") }}</dt>
  <dd>
    Configura o tempo que uma animação deveria levar para complear um ciclo.</dd>
  <dt>
    {{ cssxref("animation-iteration-count") }}</dt>
  <dd>
    Configura o numero de vezes que uma animação deveria se repetir; você pode especificar infinito para repetir a animação indefinidamente.</dd>
  <dt>
    {{ cssxref("animation-name") }}</dt>
  <dd>
    Especifica o nome da regra com parênteses (at-rule) {{ cssxref("@keyframes") }} at-rule descrevendo os keyframes da animação.</dd>
  <dt>
    {{ cssxref("animation-play-state") }}</dt>
  <dd>
    Permite voce pausar e resumir a sequência da animação.</dd>
  <dt>
    {{ cssxref("animation-timing-function") }}</dt>
  <dd>
    Configura a sincronização da animação; que é, como a animação transita por keyframes, por estabilizar curvas de aceleração.</dd>
  <dt>
    {{ cssxref("animation-fill-mode") }}</dt>
  <dd>
    Configura que valores são aplicados pela animação antes e depois de se executar.</dd>
</dl>
<h2 id="Defining_the_animation_sequence_using_keyframes">Definindo a sequência de animação usando keyframes</h2>
<p>Uma vez que você configurou a sincronização da animação, voce precisa definir a aparência da animação. Isso é feito por estabelecer duas ou mais keyframes usando a regra com parênteses (at-rule) {{ cssxref("@keyframes") }}. Cada keyframe descreve como o elemento animado deveria se renderizar a um tempo dado durante a sequência de animação.</p>
<p>Since the timing of the animation is defined in the CSS&nbsp;style that configures the animation, keyframes use a {{ cssxref("percentage") }} to indicate the time during the animation sequence at which they take place. 0% indicates the first moment of the animation sequence, while 100% indicates the final state of the animation. These two times must be specified so that the browser knows where the animation should start and finish; because they're so important, these two times have special aliases: <code>from</code> and <code>to</code>.</p>
<p>You can optionally include additional keyframes that describe intermediate steps along the way from the starting point to the ending point of the animation.</p>
<h2 id="Examples">Examples</h2>
<div class="note">
  <strong>Note:</strong> The examples here use don't use any prefix on the animation CSS properties. Older browsers may need prefixes; the live examples you can click to see in your browser also include the <code>-webkit</code><code> </code>prefixed versions.</div>
<h3 id="Making_text_slide_across_the_browser_window">Making text slide across the browser window</h3>
<p>This simple example styles the {{ HTMLElement("h1") }} element so that the text slides in from off the right edge of the browser window.</p>
<pre class="brush: css">
h1 {
  animation-duration: 3s;
  animation-name: slidein;
}

@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}
</pre>
<p>The style for the {{ HTMLElement("h1") }}&nbsp;element here specifies that the animation should take 3 seconds to execute from start to finish, using the {{ cssxref("animation-duration") }} property, and that the name of the {{ cssxref("@keyframes") }} at-rule defining the keyframes for the animation sequence is named "slidein".</p>
<p>If we wanted any custom styling on the {{ HTMLElement("h1") }} element to appear in browsers that don't support CSS&nbsp;animations, we would include it here as well; however, in this case we don't want any custom styling other than the animation effect.</p>
<p>The keyframes are defined using the {{ cssxref("@keyframes") }} at-rule. In this case, we have just two keyframes. The first occurs at 0%&nbsp;(using the alias <code>from</code>). Here, we configure the left margin of the element to be at 100% (that is, at the far right edge of the containing element), and the width of the element to be 300% (or three times the width of the containing element). This causes the first frame of the animation to have the header drawn off the right edge of the browser window.</p>
<p>The second (and final)&nbsp;keyframe occurs at 100% (using the alias <code>to</code>). The left margin is set to 0% and the width of the element is set to 100%. This causes the header to finish its animation flush against the left edge of the content area.</p>
<p>{{ CSSLiveSample("animations/cssanim1.html") }}</p>
<h4 id="Adding_another_keyframe">Adding another keyframe</h4>
<p>Let's add another keyframe to the previous example's animation. Let's say we want the header's font size to increase as it moves from right to left for a while, then to decrease back to its original size. That's as simple as adding this keyframe:</p>
<pre class="brush: css">
75% {
  font-size: 300%;
  margin-left: 25%;
  width: 150%;
}
</pre>
<p>This tells the browser that 75% of the way through the animation sequence, the header should have its left margin at 25% and the width should be 150%.</p>
<p>{{ CSSLiveSample("animations/cssanim2.html") }}</p>
<h4 id="Making_it_repeat">Making it repeat</h4>
<p>To make the animation repeat itself, simply use the {{ cssxref("animation-iteration-count") }} property to indicate how many times to repeat the animation. In this case, let's use <code>infinite</code> to have the animation repeat indefinitely:</p>
<pre class="brush: css">
h1 {
  animation-duration: 3s;
  animation-name: slidein;
  animation-iteration-count: infinite;
}
</pre>
<p>{{ CSSLiveSample("animations/cssanim3.html") }}</p>
<h4 id="Making_it_move_back_and_forth">Making it move back and forth</h4>
<p>That made it repeat, but it's very odd having it jump back to the start each time it begins animating. What we really want is for it to move back and forth across the screen. That's easily accomplished by setting {{ cssxref("animation-direction") }}&nbsp;to <code>alternate</code>:</p>
<pre class="brush: css">
h1 {
  animation-duration: 3s;
  animation-name: slidein;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}
</pre>
<p>{{ CSSLiveSample("animations/cssanim4.html") }}</p>
<h3 id="Using_animation_events">Using animation events</h3>
<p>You can get additional control over animations -- as well as useful information about them -- by making use of animation events. These events, represented by the {{ domxref("event/AnimationEvent", "AnimationEvent") }} object, can be used to detect when animations start, finish, and begin a new iteration. Each event includes the time at which it occurred as well as the name of the animation that triggered the event.</p>
<p>We'll modify the sliding text example to output some information about each animation event when it occurs, so we can get a look at how they work.</p>
<h4 id="Adding_the_animation_event_listeners">Adding the animation event listeners</h4>
<p>We'll use JavaScript code to listen for all three possible animation events. The <code>setup()</code> function configures our event listeners; we call it when the document is first loaded in order to set things up.</p>
<pre class="brush: js">
function setup() {
  var e = document.getElementById("watchme");
  e.addEventListener("animationstart", listener, false);
  e.addEventListener("animationend", listener, false);
  e.addEventListener("animationiteration", listener, false);
  
  var e = document.getElementById("watchme");
  e.className = "slidein";
}
</pre>
<p>This is pretty standard code; you can get details on how it works in the documentation for {{ domxref("element.addEventListener()") }}. The last thing the setup() function here does is set the <code>class</code> on the element we'll be animating to "slidein"; we do this to start the animation.</p>
<p>Why? Because the <code>animationstart</code> event fires as soon as the animation starts, and in our case, that happens before our code runs. So we'll start the animation ourselves by setting the class of the element to the style that gets animated after the fact.</p>
<h4 id="Receiving_the_events">Receiving the events</h4>
<p>The events get delivered to the <code>listener()</code> function, which is shown below.</p>
<pre class="brush: js">
function listener(e) {
  var l = document.createElement("li");
  switch(e.type) {
    case "animationstart":
      l.innerHTML = "Started: elapsed time is " + e.elapsedTime;
      break;
    case "animationend":
      l.innerHTML = "Ended: elapsed time is " + e.elapsedTime;
      break;
    case "animationiteration":
      l.innerHTML = "New loop started at time " + e.elapsedTime;
      break;
  }
  document.getElementById("output").appendChild(l);
}
</pre>
<p>This code, too, is very simple. It simply looks at the {{ domxref("event.type") }} to determine which kind of animation event occurred, then adds an appropriate note the {{ HTMLElement("ul") }} (unordered list) we're using to log these events.</p>
<p>The output, when all is said and done, looks something like this:</p>
<ul>
  <li>Started: elapsed time is 0</li>
  <li>New loop started at time 3.01200008392334</li>
  <li>New loop started at time 6.00600004196167</li>
  <li>Ended: elapsed time is 9.234000205993652</li>
</ul>
<p>Note that the times are very close to, but not exactly, those expected given the timing established when the animation was configured. Note also that after the final iteration of the animation, the <code>animationiteration</code> event isn't sent; instead, the <code>animationend</code> event is sent.</p>
<h4 id="The_HTML">The HTML</h4>
<p>Just for the sake of completeness, here's the HTML that displays the page content, including the list into which the script inserts information about the received events:</p>
<pre class="brush: html">
&lt;body onload="setup()"&gt;
  &lt;h1 id="watchme"&gt;Watch me move&lt;/h1&gt;
  &lt;p&gt;This example shows how to use CSS animations to make &lt;code&gt;H1&lt;/code&gt; elements
  move across the page.&lt;/p&gt;
  &lt;p&gt;In addition, we output some text each time an animation event fires, so you can see them in action.&lt;/p&gt;
  &lt;ul id="output"&gt;
  &lt;/ul&gt;
&lt;/body&gt;
</pre>
<p>{{ CSSLiveSample("animations/animevents.html") }}</p>
<h2 id="See_also">See also</h2>
<ul>
  <li>{{ domxref("AnimationEvent", "AnimationEvent") }}</li>
  <li>{{ CSS_Reference:animation() }}</li>
  <li><a href="/en/CSS/CSS_animations/Detecting_CSS_animation_support" title="en/CSS/CSS animations/Detecting CSS animation support">Detecting CSS animation support</a></li>
  <li>This <a class="external" href="http://hacks.mozilla.org/2011/06/add-on-sdk-and-the-beta-of-add-on-builder-now-available/" title="http://hacks.mozilla.org/2011/06/add-on-sdk-and-the-beta-of-add-on-builder-now-available/">post</a> from Mozilla hacks, provides two additional examples:
    <ul>
      <li><a class="external" href="http://jsfiddle.net/T88X5/3/light/" rel="freelink">http://jsfiddle.net/T88X5/3/light/</a></li>
      <li><a class="external" href="http://jsfiddle.net/RtvCB/9/light/" rel="freelink">http://jsfiddle.net/RtvCB/9/light/an</a></li>
    </ul>
  </li>
</ul>
Reverter para esta revisão