Gmail for Mobile HTML5 Series: CSS Transforms and Floaty Bars
On April 7th, Google launched a new version of Gmail for mobile
for iPhone and Android-powered devices. We shared the behind-the-scenes story through this blog and decided to share more of what we've learned in a
brief series of follow-up blog posts. This week, I'll talk about different ways to animate the
floaty bar.Even from the earliest brainstorming days for our
new version of Gmail for iPhone and Android-powered devices, we knew we wanted to try
something novel with menu actions: a context-sensitive, always-accessible UI element that
follows conveniently as a user scrolls. Thus, the "floaty bar" was born! It took us a
surprisingly long time, experimenting with different techniques and interactions, to converge
on the design you see today. Let's look under the covers to see how the animation is achieved.
You may be surprised to find that the logic is actually quite simple!
Screenshots of the floaty bar in
actionIn CSS:
.CSS_FLOATY_BAR {
...
top: -50px; /* start
off the screen, so it slides in nicely */
-webkit-transition: top 0.2s
ease-out;
...
}
In JavaScript:
// Constructor for the floaty bar
gmail.FloatyBar =
function() {
this.menuDiv = document.createElement('div');
this.menuDiv.className = CSS_FLOATY_BAR;
...
};
// Called when it's time for the floaty bar to move
gmail.FloatyBar.prototype.setTop = function() {
this.menuDiv.style.top =
window.scrollY + 'px';
};
// Called when the floaty bar menu
is dismissed
gmail.FloatyBar.prototype.hideOffScreen = function() {
this.menuDiv.style.top = '-50px';
};
gmail.floatyBar = new
gmail.FloatyBar();
// Listen for scroll events on the top level
window
window.onscroll = function() {
...
gmail.floatyBar.setTop();
...
};
The essence
here is that when the viewport scrolls, the floaty bar 'top' is set to the new viewport
offset. The
-webkit-transition rule specifies the animation parameters. (The 'top'
property is to be animated, over 0.2s, using the ease-out timing function.) This is the
animation behavior we had at launch, and it works just fine on Android and mobile Safari
browsers.
However, there's actually a better way to achieve the same
effect, and the improvement is particularly evident on mobile Safari. The trick is to use "CSS
transforms". CSS transforms is a mechanism for applying different types of affine
transformations to page elements, specified via CSS. We're going to use a simple one which is
translateY. Here's the same logic, updated to use CSS transforms.
In CSS:
.CSS_FLOATY_BAR {
...
top: -50px; /* start off the screen, so it slides in nicely */
-webkit-transition: -webkit-transform 0.2s ease-out;
...
}
In JavaScript:
// Called when
it's time for the floaty bar to move
gmail.FloatyBar.prototype.setTop = function()
{
var translate = window.scrollY - (-50);
this.menuDiv.style['-webkit-transform'] = 'translateY(' + translate + 'px)';
};
// Called when the floaty bar menu is dismissed
gmail.FloatyBar.prototype.hideOffScreen = function() {
this.menuDiv.style['-webkit-transform'] = 'translateY(0px)';
};
Upon every scroll event, the floaty bar is translated
vertically to the new viewport offset (modulo the offscreen offset which is important to the
floaty bar's initial appearance). And, why exactly is this such an improvement? Even though
the logic is equivalent, iPhone OS's implementation of CSS transforms is "
performance enhanced", whilst our first iteration
(animating the 'top' property) is performed by the OS in software. That's why the experience
was unfortunately somewhat chunky at times, depending on the speed of the iPhone
hardware.
You'll see smoother looking floaty bars coming very soon to
an iPhone near you. This is just the first in a series of improvements we're planning for the
mobile Gmail floaty bar. Watch for them in our iterative webapp, rolling out over the next
couple of weeks and months!
By Joanne McKinley, Software Engineer, Google
MobilePrevious posts from Gmail for Mobile HTML5
Series:HTML5 and Webkit pave the
way for mobile web applications
Using AppCache to launch offline - Part
1
Using AppCache to launch offline - Part
2
Using AppCache to launch offline - Part
3
A Common API for Web Storage
Suggestions for better
performance
Cache pattern for offline HTML5 web
application
Using timers effectively
Autogrowing Textareas
Reducing Startup Latency