Effective Image Buttons for HTML5 Mobile Apps

Mobile application development doesn’t always mean native apps for iPhone and Android.  If you are an experienced web developer you can use HTML5 to make great apps that have a great look and feel.

I’m working on a small HTML5 mobile app that uses toggle buttons to set the application state.  For my app, I have a bank of buttons that have two states “in” and “out”.  Here is what they look like:

Blue_out Blue_in

I used Gimp to create the buttons as PNG formatted images with transparent background.  On my first iteration, I setup the buttons using simple HTML img tags:

<img src=“Images/blue_in.png” state=‘in’ colorname=‘blue’ onclick=“toggleButton(‘blue’);”/>
<img src=“Images/reg_in.png” state=‘in’ colorname=‘red’ onclick=“toggleButton(‘red’);”/>
<img src=“Images/green_in.png” state=‘in’ colorname=‘green’ onclick=“toggleButton(‘green’);”/>

As you can see, I am storing the state of each button in the img tag itself. The toggle function looks at the current state and swaps the image around, like so:

            function toggleButton(color) {
                var button = $(‘.button_img[colorname=’ + color + ’]’);
                var colorname = button.attr(‘colorname’);
                if (button.attr(‘state’) == ‘in) {
                    button.attr(‘state’, ‘out’);
                    button.attr(‘src’, ‘Images/’ + colorname + ‘_out.png’);
                } else {
                    button.attr(‘state’, ‘in’);
                    button.attr(‘src’, ‘Images/’ + colorname + ‘_in.png’);
                }
            }

The first thing I noticed in testing was that on my Android device I was getting a very annoying green box highlighting the images when I clicked them.  You can disable this with a bit of CSS that sets the highlight color to transparent.  So I added this to my CSS:

.button_img { width: 100px; height: 100px; ‑webkit-tap-highlight-color:rgba(0, 0, 0, 0); }

So now things are looking better, but the performance isn’t really up to the standards of a native app.  When you click on a button it takes about half a second for the state to change.  My goal is to make this HTML5 app every bit as good as it’s native cousins, so this delay will never do.  The problem is that I’m binding my toggle code to the onclick event.  Due to the nature of a touch screen device, the onclick event has something close to a half second delay between the time you touch the screen and when our javascript is triggered.  A better choice is to bind to the touchstart event.  That is called immediately when our button is pressed without any undo delay.  This code is a little trickier because you can’t define it right in the img tag.  You can do all this with standard JavaScript using the addEventListener function, but I love jQuery, so my new code looks like this:

          $(document).ready(function () {
                $(‘.button_img’).each(function () {
                    $(this).bind(‘touchstart’, toggleColorTouch);
                });
            });

            function toggleColorTouch(e) {
                toggleButton($(e.target).attr(‘selectcolor’));
            }

Ahh, now this is looking really good.  One final thing is missing though…there is no auditory or tactile feedback.  That’s not everyone’s cup of tea, but if you want it is easy enough to add.  You can trigger audio feedback using HTML5’s audio tag and API.  Just put this audio tag in in your HTML:

    <audio id=“sound_click” src=“click.wav” preload=“auto”></audio>

Then when you toggle the button, trigger the sound:

            function toggleColorTouch(e) {
                document.getElementById(‘sound_click’).play();
                toggleButton($(e.target).attr(‘selectcolor’));
            }

Older Android devices have some lag problems with the audio tag.  So if you are targeting Android, either use an alternate method or make sure you test this out on the devices you want to support.