The question occasionally comes up about the exact specifications for the built-in Windows animations that express the Windows look and feel. Often this is because someone wants to replicate the effect outside of Windows, such as on a website, or within a webview element where WinJS isn’t accessible.

Fortunately, it’s quite simple to see the implementation of the animations directly in the WinJS source code. All the animations stuff is right near the top of the ui.js file, with the WinJS.UI.Animation namespace starting around like 530/540. You can also just search for the specific animation’s name, and you’ll find code like this (omitting comments):

fadeIn: function (shown) {
return thisWinUI.executeTransition(
shown,
{
property: “opacity”,
delay: 0,
duration: 250,
timing: “linear”,
from: 0,
to: 1
});
},

WinUI.executeTransition is a helper function that takes the property bag indicated here and creates the transition/animation. In this case it animates the opacity property from 0 to 1 with no delay over 250ms using linear timing. And this is exactly the “spec” for the system-wide Windows fade-in effect, which is also expressed in the XAML animations and so forth.

It’s worth mentioning too that an app can also retrieve these characteristics–called animation metrics–through the Windows.UI.Core.AnimationMetrics API in WinRT (refer also to the Animation metrics sample.) This API exists primarily for DirectX apps written in C++ that don’t have a built-in animation library to draw from and therefore must replicate the behaviors at runtime. But you can use the metrics from any language to do the same if needed.


Similar to last week’s two posts about simple thing that are easy to forget, we also have the fact that not all properties of HTML elements and not all CSS style properties can be animated with CSS animations and transitions (including WinJS.UI.executeTransition and similar helpers). For example, someone asked a question a while ago about some code that was attempting to animateĀ an element’sĀ scrollLeft property, but it wasn’t working. This is simply because scrollLeft isn’t an animatable property! In that case, the proper answer is to animate the desired motion using the transform property.

I have to say that I don’t know where a definitive list exists of what properties can or cannot be animated, but let me frame the question differently. When you use CSS animations or transitions on the transform and/or opacity properties, those animations will run “independently” in the GPU. Animating anything else–if it can be animated–runs “dependently” which means in the CPU and on the UI thread, which will typically perform poorly on less powerful devices. Similarly, you can always animate any property you want using requestAnimationFrame, but those always run on the UI thread as well.

The best practice, in short, is to always think how you can achieve the effect you want through transform and opacity. If you can’t, and must do a dependent animation, try it with CSS animations/transitions, and if that doesn’t work, then roll your own with requestAnimationFrame.


In any discussion about animations, the GPU always comes up for good reason: anything that runs in the GPU will simply perform better in terms of UX and power consumption. If you hear the term “independent animation,” this refers to an animation that fully runs in the GPU. A “dependent animation” is one that runs on the UI thread.

In JavaScript, anything that you animate directly within setInterval, setTimeout, and requestAnimationFrame is a dependent animation, because you’re clearly doing all the work in code. This is unavoidable in many scenarios, like games, but then the point of the game is to play with graphics and animations so you’re not quite as worried about the GPU. It’s worth noting that at present, apps written in JavaScript don’t have access to the GPU outside of doing independent animations via CSS. Eventually I imagine that WebGL will become available which should change that story.

To run a CSS animation in the GPU, the key thing to remember is that you must be animating only the opacity and transform properties of an element. That’s it. You can actually do quite a bit with just these two properties: any kind of fades along with manipulations of size, 2D and 3D rotation, perspective, and so on. It just means that you need to be aware of how you and third-party libraries you might use define animations.

The animations library in WinJS.UI.Animation are all defined to be independent. The little bounce animation for a button click, pointerDown, for example, does a 97% scale transform, and its counterpart, pointerUp, restores the scale to 100%. You could, of course, achieve the same effect through the margin or padding properties, but then the animation would run in the UI thread.

In designing your dynamic UX, then, really become versed in what you can achieve with opacity and transform, and design around that. If, on occasion, you need dependent animations, that’s fine too. Just be careful to not overuse them to keep your app performing its best.