Responsive button feedback in PhoneGap apps: a better alternative to -webkit-tap-highlight-color
Filed in: android, apps, Cordova, css, iOS, PhoneGap, Uncategorized, zepto
I don’t think I’m alone when I say that the most important thing with a PhoneGap app is that it feels responsive to a users touch. It goes without saying that the easiest argument that web/hybrid app neigh-sayers have is touch response lag. The first thing they’re going to point fingers at and tweet to their native compadres is how many milliseconds it takes for a button to light up when it is touched.
Feedback is important.
Mobile webkit browsers know feedback is important
They really do. Touch any (ok, most) hyperlinks in mobile Safari or Chrome and, unless the developer has overwritten the default event, it will rather delightfully light up the link text/button in a grey background glow. Instant feedback that you have touched something. This is a realtime event that fires the millisecond that you tap a hyperlink. There is no 300ms delay, that you find with click
events if you’re using Javascript.
This effect occurs due to a CSS property called -webkit-tap-highlight-color
.
The [aesthetic] problems with -webkit-tap-highlight-color
The problem with -webkit-tap-highlight-color
is that, other than the colour itself, there is no control over the appearance of it. And while it’s acceptable for text links it’s terrible when put into practice on a beautiful interface where you want to highlight a button being tapped… the very millisecond it is tapped.
The reason it’s terrible is that -webkit-tap-highlight-color
effectively puts a rectangular background, with a 3px, or so, corner radius, over the hyperlink. It also gives the highlight a padding
of about 3px. Take a look at what it does:

Let’s look at that a little bit closer.

That’s something pretty ghastly that you have no control over, other than the background colour itself.
Fortunately you can easily modify the grey background glow with a CSS property called -webkit-tap-highlight-color
that you can use to set the colour of the highlight using RGBa
. Like so:
a { -webkit-tap-highlight-color: rgba(255,0,0,0.5); }
Now the grey background glow is gone. And replaced with a red background glow. Good times. Except it’s not.
A better alternative to -webkit-tap-highlight-color
Recently I’ve been using a simple alternative to using this property. It yields the same responsive feel while retaining full control over the appearance. It’s not a pure CSS solution, but that’s OK as you will be using JavaScript in your app anyway.
There are several steps to this alternative:
Suppressing the -webkit-tap-highlight-color
Firstly you will need to prevent -webkit-tap-highlight-color
from being applied appearing when you tap a hyperlink. That’s just a bit of CSS:
a { -webkit-tap-highlight-color: rgba(0,0,0,0); }
What this does is overwrite the default -webkit-tap-highlight-color
, for a
elements, with a completely transparent colour. In this case, black with an alpha-transparency of 0—completely transparent.
Creating a custom tap highlight colour
Secondly you will need to create one, or more, custom tap highlight colours to add – when a touch event occurs – to your link/button elements.
I’m going to use a really common design trend in app buttons that I’m seeing at the moment. I call it the active gradient mirror style. It goes something like this; a button will have a vertical gradient background – light grey to a darker grey for example – for its inactive state. It’s tapped, active, state will mirror the gradient—in this example, dark grey to a lighter grey. The iOS and Android Instagram and Twitter apps use this technique to great effect with their buttons.
Something like this:

a { background: -webkit-linear-gradient(top, rgba(0,0,0,0.1) 0%,rgba(0,0,0,0.3) 100%); background: linear-gradient(to bottom, rgba(0,0,0,0.1) 0%,rgba(0,0,0,0.3) 100%); } a.tapped { background: -webkit-linear-gradient(top, rgba(0,0,0,0.3) 0%,rgba(0,0,0,0.1) 100%); background: linear-gradient(to bottom, rgba(0,0,0,0.3) 0%,rgba(0,0,0,0.1) 100%); }
Note: I am only using the webkit vendor prefix (to support older mobile webkit browsers versions) and the W3C linear-gradient specification, used in current webkit browser versions, for the purposes of this example.
Rather self-explanatory this. A base, inactive, a
element background and a tapped (active) class that can be added to the a
element when touch events are fired.
Handling the touch events with a bit of Javascript to complete the effect
Now that the CSS is complete the effect just requires a few lines of Javascript to handle the touch events. There are a number of things to bear in mind here.
- when a finger is touching a button
- when a finger stops touching a button
- when a finger taps a button
That’s quite a few things to be constantly looking out for. And while jQuery might be your go-to JavaScript library, it doesn’t support touch events out of the box. But there is an alternative JavaScript library, that you’ve likely heard of of – if not already used – that is optimised for touch events. It’s called Zepto.js and it makes checking the for above events a breeze. It’s also considerably lighter in file size than jQuery’s ever-bloating core library.
Using zepto.js to manage the button touch states
Firstly let’s add an ‘active’ class to a button when it is touched and remove it when it is no longer being pressed:
$('a').on('touchstart', function(e){ $(this).addClass('tapped'); }); $('a').on('touchend', function(e){ $(this).removeClass('tapped'); });
So here we’re leveraging two touch events; touchstart and touchend. Both of these events occur instantaneously. This pretty much completes the effect. To go a step further and handle a tap event is simple with zepto.js is simple too:
$('a').on('tap', function(e){ e.preventDefault(); //do your thing return false; });
Here is a short video of the effect in action.
It’s worth noting that Zepto.js handles tap
events in a specific way. A tap
event is triggered when a button is touched and the finger is released within 750ms. If the finger remains touching the button for longer than 750ms the tap
event will not fire. The touchstart
event (where we have added a tapped class above) will remain, however, until the finger is released.
And there you have it. Simple, streamlined and super-responsive buttons in your PhoneGap app.
-
Paul Clegg
-
Sam Croft
-
-
Paul Clegg
-
Sam Croft
-
-
John
-
jeliasson
-
-
John
-
jeliasson
-
-
imissmyjuno
-
Sam Croft
-
imissmyjuno
-
Sam Croft
-
-
-
-
imissmyjuno
-
Sam Croft
-
imissmyjuno
-
Sam Croft
-
-
-
-
Holda
-
Holda
-
Velda
-
Velda
-
Clay
-
Clay
-
Ethan Collins
-
Sam Croft
-