CSS3 for Windows Store Apps: Transitions

CSS3-LogoWindows 8 brings in a new era of opportunity for the web developer/designer in that applications in the Windows Store can be written with “web” technologies such as HTML5, JavaScript, and CSS3. Creating a compelling user experience is an important aspect of a successful app, and CSS3 is a fantastic way to reach that objective.  This post will specifically address a great way to enable fast and fluid interactions in your app by using CSS3 Transitions.

If you haven’t been using transitions or know what they even do, then let’s start with a quick description:  Transitions allow content on the screen to change from one visual state to another in a gradual, animated way.  To learn more about the basics of transitions, check out the Transitions topic at the IE 10 Guide for Developers, and play with the Hands On: transitions on IE Test Drive.  The focus here will assume you know the fundamentals of transitions and want to how to use them when developing apps for the Windows Store.

Transitions from Web to App

Will you need to define transitions differently for apps than for web pages?  Technically, the answer is no. But you may not need to work so hard. For example, consider the following CSS rule:

 .transit {
  -webkit-transition: all 0.4s;  
     -moz-transition: all 0.4s; 
       -o-transition: all 0.4s;  
          transition: all 0.4s; 
}

When developing for the web, we worry about web things – such as supporting multiple browsers. This is not a worry when developing an app for the Windows Store. This means you don’t have to riddle your CSS with all the vendor prefixes as seen above.  Therefore the above rule is reduced and far more simple to read and manage as seen here:

 .transit {
   transition: all 0.4s; 
}

When a transition is defined, it specifies what properties are targeted for animation and for how long.  In the example above, the all keyword means all animatable properties.  A transition is triggered when any targeted property value changes. A common scenario where values are changed is when using CSS pseudo classes such as :active, :checked, :disabled, :enabled, :focus, :hover, :invalid, and :valid are in play.  Hovering is one of the most common uses of transitions, as seen here:

 .box {
   background-color: #FFFFFF;
         transition: background-color 1s;
}

.box:hover {
   background-color: #FF0000;
}

The above example fades from white to red and smoothly back again when hovering.  Although hover effects are appealing, keep in mind that Windows 8 is an operating system designed to fully embrace touch screen devices.  Hovering works well with a mouse, but not with a finger.  One possible way to deal with this is seen here:

 .box {
   background-color: #FFFFFF;
         transition: background-color 1s;
}

.box:hover, .box:active {
   background-color: #FF0000;
}

The subtle change above is adding the :active pseudo class if the targeted element is pressed down.  This may not be practical in some circumstances, but it at least involves use touch devices when using you app.

Transitions in View States

Another way transitions are triggered is by use of media queries.  Windows 8 applications can run in multiple layouts, and media queries can respond to layout changes by responding to the view state.  Here is an example of a style sheet shell with media queries for each supported view state:

 /* shared css rules go here */

/* media queries for adapting to layout changes */
@media (-ms-view-state: filled) { }
@media (-ms-view-state: fullscreen-landscape) { }
@media (-ms-view-state: fullscreen-portrait) { }
@media (-ms-view-state: snapped) { }

It is useful to know that transitions can be triggered by layout changes because proper use of them can enhance the fluidity of the application.  For example, a switch to a snapped layout might require a change in font size.  With just a subtle transition, you can get the effect of a graceful move to snapped view and back.  This is demonstrated in the following CSS rules:

 .subheader {
     /* recommended subheader size */
     font-size : 20pt;
    font-family: 'Segoe UI Light';
          color: rgba(255,255,255,1.0);

     /* subtle shrink|grow effect */
     transition: font-size ease 0.3s;
}

@media (-ms-view-state: snapped) {
    .subheader {
        /* recommended subheader size for snapped */
        font-size: 11pt;
    }
}

When the rules are implemented above, a switch in the application to a snapped position will create a simple shrink effect.  When switching out of snapped view, the text quickly grows.  Careful use and experimentation can lead to a polished user experience.

Transitions in Code

While changes to targeted properties of a transition can be defined in the CSS rules, another way to make property changes programmatically through JavaScript.

Transitions are always timed.  One way to interact with a transition in code is to respond to the transitionend event when it is complete.  To demonstrate, first look at the following CSS rule:

 .demo-transition-end {
    transition: all 4s;
}

.demo-transition-end:active {
        background-color: #FF0000;
               transform: rotate(360deg);
}

Now here is an example of code that responds to an element on the page that is the target of a CSS transition rule above:

 var box = document.querySelector("#box");
box.addEventListener("transitionend",
    function (args) {
        if (args.elapsedTime < 4) {
            box.innerText = "Keep Pressing!";
        }
    }
);

In the code above, an anonymous function is used as the event handler when the transition ends.  Note that the argument supplied to the function has an elapsedTime property, allowing you to determine how long the transition lasted.  Because the transition is triggered by the :active pseudo class, it will only reach 4 seconds if the user continues to press down on the element.  The code above detects the user let go too soon, and changes the text of the element to encourage the user to keep pressing.

To continue with this example, a new class rule will be added:

 .vanish {
    transition-delay: 1s;
           transform: scale(0.01);
             opacity: 0.01;
}

Now an else clause will be added to the event handler, so that the complete code now looks like this:

 var box = document.querySelector("#box");
box.addEventListener("transitionend",
    function (args) {
        if (args.elapsedTime < 4) {
            box.innerText = "Keep Pressing!";
        } else {
            box.innerText = "Let Go...";
            box.classList.add("vanish");
        }
    }
);

The code now responds if the transition reached a full 4 seconds.  If that happens, it changes the text of the element to “Let Go…”.  It also calls on the element’s classList property, and adds a new class named vanish.  The addition of the class rule will invoke another transition that will make the element shrink and disappear in 1 second.

The classList property allows you to easily change the the state of the class attribute, which will invoke a transition if any targeted property values change.  You can use classList  for adding, removing, inspecting, or toggling class names in the attribute.  You can also simply change any of the elements style property values directly to also invoke a transition.

Transitions Beyond

Fans of CSS3 transitions will enjoy knowing that such powers are easily tapped when developing Windows Store apps with JavaScript.  You should also be aware that the WinJS.UI.Animation API contains methods for transitioning content as well.

Have fun coding, and be sure to benefit from all the resources available to you at Generation App!