Animation on mobile is simple.

It’s also easier to animate correctly on mobile… If you take our advice.

While everyone now uses CSS3 for animation, many people don’t do it properly. Many best practices that should be considered are often ignored because there are still people who don’t understand what they really mean.

With so many device specifications these days, if you don’t tailor your code specifically, a poor user experience will kill you.

Remember: while there will always be high-end flagships pushing the envelope, you’ll still be dealing with low-end devices that are toys compared to these performance monsters.

We want to help you navigate CSS3 properly. A few things to know first.

Understand the timeline

What does the browser do when rendering and processing HTML elements? This timeline is called the Critical Render path.

For smooth animation we need to focus on the effect of changing properties on the Composite stage, not the other stages.

Style 1.

The browser begins to calculate the style applied to the element — the recalculated style.

2. Layout

Next, the browser begins to generate a shape and position for each element — the layout. This is where the browser sets page properties such as width and height, and margin or left, top, right, and bottom.

3. Apply colours to a drawing

The browser starts filling the layer with pixels. The attributes to use are box-shadow, border-radius, color, background-color, and so on.

4. The synthesis of

This is where you get your hands dirty, because browsers start drawing all the layers onto the screen.

Modern browsers can run four styles perfectly using transform and opacity.

  • location– transform: translateX (n) translateY(n) translateZ(n);
  • The zoom– transform: scale (n);
  • rotating– transform: the rotate (n deg);
  • transparent– opacity:n;

How do you get to 60 frames per second

With an idea in mind, let’s roll up our sleeves and get to work.

We start with HTML, create a very simple structure, and put the elements of class app-Menu inside the elements of class Layout.

<div class="layout">
    <div class="App - menu"></div>
    <div class="Header"></div>
</div>Copy the code

mistake

.app-menu {
  left: -300px;
  transition: left 300ms linear;
}

.app-menu-open .app-menu {
  left: 0px;
  transition: left 300ms linear;
}Copy the code

See these properties that we changed? You should avoid using the left, top, right, bottom properties for Transitions. Their updates cause browsers to create layouts every time, affecting all of their child elements and making it difficult to animate smoothly.

The result is this:

This animation is not smooth at all. We checked out what’s going on behind the scenes with developer tools. Here it is:

It is clear that FPS is very irregular and performance is poor.

The use of the Transform

.app-menu {
  -webkit-transform: translateX(-100%);
  transform: translateX(-100%);
  transition: transform 300ms linear;
}

.app-menu-open .app-menu {
  -webkit-transform: none;
  transform: none;
  transition: transform 300ms linear;
}Copy the code

The transform property affects the composition phase. Here the browser is told that the layer is about to be rendered and is ready to execute the animation, so the animation renders with less lag.

Timeline:

It’s starting to work, the FPS is getting regular, and the animation is getting smoother.

FPS are getting better and more stable, and the animations are smoother.

Use GPU to perform animation

One hundred feet ahead. To make the animation “silky smooth”, we next used the GPU to render.

.app-menu {
  -webkit-transform: translateX(-100%);
          transform: translateX(-100%);
  transition: transform 300ms linear;
  will-change: transform;
}Copy the code

While some browsers still require translateZ() or translate3D () as an alternative, will-change’s widespread support is overwhelming. Its function is to elevate elements to another layer so that browsers don’t have to worry about layout rendering or drawing.

How smooth can this animation be? Look at the timeline:

FPS animations are more stable and render faster. But one frame was still rendering for a long time. There was a bit of a bottleneck at the beginning.

Remember the HTML structure you created at the beginning? We use JavaScript to control the app-Menu div.

function toggleClassMenu(a) {
  var layout = document.querySelector(".layout");
  if(!layout.classList.contains("app-menu-open")) {
    layout.classList.add("app-menu-open");
  } else {
    layout.classList.remove("app-menu-open");
  }
}
var oppMenu = document.querySelector(".menu-icon");
oppMenu.addEventListener("click". toggleClassMenu. false);Copy the code

The problem was adding the class name to the Layout element, and we made the browser evaluate the style more than once — which affected the rendering.

Silky smooth 60 FPS

What if we create menus outside of Windows? This separate area ensures that only elements that need to be animated are affected.

Therefore, we improved the following HTML structure:

<div class="menu">
    <div class="app-menu"></div>
</div>
<div class="layout">
    <div class="header"></div>
</div>Copy the code

You can also control the state of the menu in a slightly different way. We remove the CSS class that controls the animation after monitoring the end of the animation using JavaScript’s TransitionEnd method.

function toggleClassMenu(a) {
  myMenu.classList.add("menu--animatable");
  myMenu.classList.add("menu--visible");
  myMenu.addEventListener("transitionend". OnTransitionEnd. false);
}
function OnTransitionEnd(a) {
  myMenu.classList.remove("menu--animatable");
}
var myMenu = document.querySelector(".menu");
var oppMenu = document.querySelector(".menu-icon");
oppMenu.addEventListener("click". toggleClassMenu. false);Copy the code

Now put them together and see what happens.

Here is a perfectly correct example of using CSS3 to implement animation:

.menu {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  pointer-events: none;
  z-index: 150;
}

.menu-visible {
  pointer-events: auto;
}

.app-menu {
  background-color: #fff;
  color: #fff;
  position: relative;
  max-width: 400px;
  width: 90%;
  height: 100%;
  box-shadow: 0 2px 6px rgba(0. 0. 0. 0.5);
  -webkit-transform: translateX(-103%);
  transform: translateX(-103%);
  display: flex;
  flex-direction: column;
  will-change: transform;
  z-index: 160;
  pointer-events: auto;
}

.menu-- -visible.app-menu {
  -webkit-transform: none;
  transform: none;
}

.menu- -animatable.app-menu {
  transition: all 130ms ease-in;
}

.menu--visible.menu-- -animatable.app-menu {
  transition: all 330ms ease-out;
}

.menu:after {
  content: ' ';
  display: block;
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(0.0.0.0.4);
  opacity: 0;
  will-change: opacity;
  pointer-events: none;
  transition: opacity 0.3 s cubic-bezier(0.0.0.3.1);
}

.menu.menu--visible:after{
  opacity: 1;
  pointer-events: auto;
}Copy the code

What about the timeline?

It’s silky smooth, right?