CSS3 Transitions and Transforms in Gmail for the iPad
The Mobile Gmail team recently announced a new
stacked cards interface for the iPad. In this interface we make
use of CSS3 transitions and transforms to provide a more intuitive interface that has a look
and feel that is similar to native applications. In this post we will describe CSS3
transitions and transforms and how they were used to develop this interface. All of the CSS
and JavaScript examples currently work only in WebKit-based browsers, such as Safari on the
iPad. However, Mozilla-based browsers have their own versions of WebKit-based extensions that
use the ‘
-moz’ prefix, and that should behave similarly.
CSS3 Transitions CSS3 transitions allow the browser to animate the change of a CSS
property from an initial value to a final value. A transition is configured by setting four
CSS properties on an HTML element:
-webkit-transition-property
-webkit-transition-duration
-webkit-transition-timing-function
-webkit-transition-delay
The
-webkit-transition-property
property identifies the CSS properties
where changes to the property will trigger a transition between the old value of the property
and the new value. The
-webkit-transition-duration
property
specifies, in milliseconds, the length of time over which the transition should take place.
The
-webkit-transition-timing-function
property describes
the speed at which the transition progresses over the duration of the transition. For example,
-webkit-transition-timing-function: ease-in-out
describes
a transition that will proceed slowly at the beginning and the end of the transition, but that
will proceed quickly during the middle of the transition. You can also provide a custom,
cubic-bezier function for a higher degree of control over the timing. The
-webkit-transition-delay property specifies a delay, measured in
milliseconds, before the transition begins.
The transition properties
can also be set simultaneously using the
-webkit-transition
property,
by simply specifying them in the above order. Once the transitions properties are set and up
to the point where the value of
-webkit-transition-property
is
changed, all modifications of the specified CSS properties will trigger transitions.
CSS3 Transforms CSS3 transforms allow the rendering of an HTML element to be
modified using 2D and 3D transformations such as rotation, scaling, and translations.
Transforms are applied by setting the
-webkit-transform
CSS property
with the desired list of transforms. Each transform takes the form of a transformation
function, such as
translate3d
or
rotate
, and
a list of parameters enclosed in brackets. For example, to move an object to the right by 100
pixels and rotate it by 45 degrees you can use the
-webkit-transform
property:
-webkit-transform: translate(100px, 0)
rotate(45deg);
Using
-webkit-transform
as the transition property when moving an element
is advantageous relative to using the standard
top
and
left
properties because transitions using
-webkit-transform
are hardware-accelerated in Safari. An exception
here is that it seems that 2D translations are
not hardware-accelerated. But, since any 2D translation is
equivalent to a corresponding 3D translation with the same translations in the x and y and no
translation in the z axis, it is easy to use a hardware accelerated
translate3d(x,
y, 0) transform instead of a non-hardware accelerated
translate(x,
y)
transform.
Terminology There are a few terms here that begin with ‘trans,’ and they can easily be
confused if you are not familiar with them. Here they are again:
- Transition: An implicit animation of CSS properties between an initial and a final
value.
- Transform: A modification to the appearance of an HTML element by
manipulating it in a 2D or 3D space.
- Translation: A particular type of
transformation that moves the HTML element in 2D or 3D
space.
Stacked Cards Interface In the stacked cards interface, cards representing selected conversations transition onto
the screen when their corresponding conversation is selected, and transition off of the screen
when it is deselected.
When cards are selected, they are transitioned
out from underneath the conversation list on the left side of the application into the
selected conversation area on the right side of the application. To move the card onto the
screen, we set an initial transform, configure the transition, and finally apply the desired
final transform to the element.
To simplify the layout, the
un-transformed position of each card is its normal position in the selected conversation area.
This allows the card to have no translation applied when in this position, although it will
need a translation to animate the movement. Initially the card has a transform that translates
it to the left. The z-index property is used to ensure that the card will render underneath
the conversation list. The rotation of the card is also initially applied, since we chose not
to have the card rotate as it transitions onto the screen.
card.style.WebkitTransform =
‘translate3d(-700px, 0, 0) rotate(5deg)’;
Since the
particular translation and rotation can vary, we chose to apply this property using JavaScript
rather than including it in the CSS class applied to the card. It is important that the CSS3
transition is not yet applied because we do not want this transform to be a transition.
Moreover, it is important that the card is rendered at its initial transform before the
transition is configured and the destination transform is applied. This is easily achieved by
wrapping these next steps in a call to
window.setTimeout with a
timeout of 0 ms.
window.setTimeout(function()
{
card.style.WebkitTransition =
‘-webkit-transform 300ms
ease-in-out’;
card.style.WebkitTransform =
‘translate3d(0, 0, 0)
rotate(5deg)’;
}, 0);
Completion of
the Transition It is useful to know when the transition is
complete. In the stacked cards interface, we use this to improve performance by setting
display:none on obscured cards so that they do not need to be
rendered. Adding an event listener allows the application to be notified when the transition
has completed.
element.addEventListener(‘webkitTransitionEnd’, listener,
false);
Interrupting a Transition
In some cases, you may want to change a transition while it is in
progress. For example, if the user unselected a conversation while the corresponding card was
still animating onto the screen, we might apply a new transition to send the card back off of
the screen again. When you apply a new CSS value while a transition is already in progress, a
new transition will occur between the current value of the property in the transition and the
new value that you apply. For example, suppose a card is halfway through it’s transition onto
the screen, and we apply this CSS transform:
card.style.WebkitTransform =
‘translate3d(-700px, 0,
0) rotate(5deg)’;
Since the transition properties are
still configured, a new transition will occur. The initial value for the transition will be
the halfway point - approximately
translated3d(-350px, 0, 0)
rotate(5deg).
The final value will be
translate3d(-700px, 0, 0)
rotate(5deg).
The full duration of the transition will still apply, so the card
will move about half as quickly as it usually does. It is possible to determine the current
transform applied to an HTML element using the
WebKitCSSMatrix and to use this to recalculate more appropriate
transition parameters, but this is outside the scope of this post.
Conclusion I hope that this introduction to CSS3
transitions and transforms has been useful, and that the insight into the implementation of
Mobile Gmail on the iPad has been interesting. Based on positive feedback, the Mobile Gmail
team is looking forward to making more use of transitions and transforms in the future.
By Liam Asher
Segel-Brown, Software Engineering Intern, Google Mobile