Skip to content

Commit c41361f

Browse files
committed
animation
1 parent 9b99012 commit c41361f

File tree

1 file changed

+50
-12
lines changed

1 file changed

+50
-12
lines changed

7-animation/2-css-animations/article.md

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -407,29 +407,67 @@ There are many articles about `@keyframes` and a [detailed specification](https:
407407

408408
You probably won't need `@keyframes` often, unless everything is in constant motion on your sites.
409409

410-
## Performance of CSS animations
410+
## Performance
411411

412412
Most CSS properties can be animated, because most of them are numeric values. For instance, `width`, `color`, `font-size` are all numbers. When you animate them, the browser gradually changes these numbers frame by frame, creating a smooth effect.
413413

414-
However, not all animations will look as smooth as you'd like, because different CSS properties cost differently to change. Among all the properties, `transform` and `opacity` are the cheapest to animate, and produce the highest framerate, so in real life projects, you should try to only use these two to achieve your desired effects.
415-
416-
The reason for this is when something is being _transformed_, the browser engine is able to only worry about changing the look of this one thing, without touching other existing things on the page. Same for opacity change.
414+
However, not all animations will look as smooth as you'd like, because different CSS properties cost differently to change.
417415

418416
In more technical details, when there's a style change, the browser goes through 3 steps to render the new look:
419417

420418
1. **Layout**: re-compute the geometry and position of each element, then
421-
2. **Paint**: re-compute how everything should look like, including "layers" which is a big deal, then
422-
3. **Composite**: render the final results into pixels on screen.
419+
2. **Paint**: re-compute how everything should look like at their places, including background, colors,
420+
3. **Composite**: render the final results into pixels on screen, apply CSS transforms if they exist.
421+
422+
During a CSS animation, this process repeats every frame. However, CSS properties that never affect geometry or position, such as `color`, may skip the Layout step. If a `color` changes, the browser doesn't calculate any new geometry, it goes to Paint -> Composite. And there are few properties that directly go to Composite.
423+
424+
The Layout step is by far the most expensive: geometry calculations take time. And the delays are actually visible on most devices, leading to a bit more "jittery", less fluid animations.
425+
426+
**The general recomendation is to animate properties that don't do Layout.**
427+
428+
For most CSS properties, the rule is simple: if its change may affect geometry, move elements (even in theory), then it triggers Layout. Otherwise (e.g. a `color` change may not shift elements around), the browser directly goes to Paint. You can find a longer list of CSS properties and which stages they trigger at <https://csstriggers.com>.
429+
430+
The `transform` property is a notable exception:
431+
- CSS transforms affect the target element box as a whole (rotate, flip, stretch, shift it).
432+
- CSS transforms never affect neighbour elements.
433+
434+
So browsers apply `transform` "on top" of existing Layout and Paint calculations, in the Composite stage.
435+
436+
In other words, the browser calculates the Layout (sizes, positions), paints it with colors, backgrounds, etc at the Paint stage, and then applies `transform` to element boxes that need it.
437+
438+
Animating the `transform` property never causes Layout and Paint. More than that, the browser leverages the graphics accelerator (a special chip on the CPU or graphics card) for CSS transforms, thus making them very effecient.
439+
440+
Luckily, the `transform` property is very powerful. By using `transform` on an element, you could rotate and flip it, stretch and shrink it, move it around, and [much more](https://developer.mozilla.org/docs/Web/CSS/transform#syntax).
441+
442+
The `opacity` property also never causes Layout. We can use it for show / hide or fade-in / fade-out effects.
443+
444+
Paring `transform` with `opacity` can usually solve most of our needs, providing fluid, good-looking animations.
423445

424-
During CSS animation, this process repeats every frame. You can check [how each CSS change triggers these steps](https://csstriggers.com/), and you'll find most changes will trigger ` 1` `2` `3`, while color change only triggers `2` `3`, and transform and opacity only trigger `3`.
446+
For example, here clicking on the `#boat` element adds the class with `transform: translateX(300)` and `opacity: 0`, thus making it move `300px` to the right and fade out:
425447

426-
Luckily, `transform` is by far the most useful and most powerful property to animate. By using `transform` on an element, you could rotate and flip it, stretch and shrink it, move it around, and [many more](https://developer.mozilla.org/docs/Web/CSS/transform#syntax).
448+
```html run height=260 autorun no-beautify
449+
<img src="https://js.cx/clipart/boat.png" id="boat">
427450

428-
Meanwhile, `opacity` can help with show / hide or fade-in / fade-out effects. By paring `transform` with `opacity` you can usually solve all your needs, for example:
451+
<style>
452+
#boat {
453+
cursor: pointer;
454+
transition: transform 2s ease-in-out, opacity 2s ease-in-out;
455+
}
456+
457+
.move {
458+
transform: translateX(300px);
459+
opacity: 0;
460+
}
461+
</style>
462+
<script>
463+
boat.onclick = () => boat.classList.add('move');
464+
</script>
465+
```
466+
467+
Or a more complex example, with `@keyframes`:
429468

430469
```html run height=80 autorun no-beautify
431470
<h1 onclick="this.classList.toggle('animated')">click me to start / stop</h1>
432-
433471
<style>
434472
h1.animated {
435473
animation: hello-goodbye 1.8s infinite;
@@ -452,8 +490,6 @@ Meanwhile, `opacity` can help with show / hide or fade-in / fade-out effects. By
452490
</style>
453491
```
454492

455-
In earlier examples in this chapter, we've animated `font-size`, `left`, `width`, `height`, etc. In real life projects, they could be replaced by `transform: scale()` and `transform: translate()` for better performance. <!-- More on this topic [here](https://web.dev/animations-overview/) and [here](https://web.dev/animations-guide/). -->
456-
457493
## Summary
458494

459495
CSS animations allow smoothly (or not) animated changes of one or multiple CSS properties.
@@ -469,6 +505,8 @@ Limitations of CSS animations compared to JavaScript animations:
469505
- Not just property changes. We can create new elements in JavaScript as part of the animation.
470506
```
471507

508+
In earlier examples in this chapter, we animate `font-size`, `left`, `width`, `height`, etc. In real life projects, we should use `transform: scale()` and `transform: translate()` for better performance.
509+
472510
The majority of animations can be implemented using CSS as described in this chapter. And the `transitionend` event allows JavaScript to be run after the animation, so it integrates fine with the code.
473511

474512
But in the next chapter we'll do some JavaScript animations to cover more complex cases.

0 commit comments

Comments
 (0)