logo

Using Image Sprites To Add Icons to HTML Input Buttons

Remember way back I talked about using buttons with the same name as a Field to make accessible forms that needed no JavaScript yet knew which button a user had pressed. The HTML looks like this:

<input type="submit" name="Action" value="Approve" />
<input type="submit" name="Action" value="Reject" />

On the Form we have a field called "Action" too and we can inspect its value to find out what the user wanted to do. All works well and it's a trick I've used a few times in the six years since I first talked about it.

Yeah, and? Well, the other week I talked about making nice-looking buttons. How about we marry up the two techniques and make an accessible Form with nice-looking buttons!?

Let's say we want the user to choose between three buttons on a questionnaire form -- Yes, No and Skip. The HTML is like so:

<input type="submit" name="Answer" value="Yes">
<input type="submit" name="Answer" value="No">
<input type="submit" name="Answer" value="Skip">

In a browser this would look something like this:

image

Pretty boring, right? It's crying out for some extra style. The trouble with using CSS to style input-type buttons is that once you add any styles they start to look all a bit weird and it's nigh on impossible to get a consistent appearance across all browsers. That's why I prefer to using images as buttons (see link above).

Here's the same form but with a button-like image used as the background of the buttons:

image

Looks better, no?

The CSS for this is quite simple:

.buttons input, 
.buttons input:focus, 
.buttons input:active, 
.buttons input:hover {
        font-weight: bold;
        color: #333;
        width: 143px;
        height: 40px;
        border: none;
        cursor: pointer;
        text-transform: uppercase;
        background: transparent url(button.png) no-repeat 0% 0%;
}

It could look a little better still though. How about adding some icons to the buttons to help the user distinguish between them. The trouble with this is that the humble <input> element won't let you add child elements and we've already added a background, so we can't add another and we don't want to use a separate background image for each button now, do we!?

This is where sprites come in! Here's the image I'm going to use as a sprite:

With a sprite we can use this single image as the background for all three and simply offset it's position by the right number of pixels to make it appear like a different button. The advantage of sprites being that there's less network traffic to load 1 image than to load 3 (or more), so the page loads quicker!

Using the sprite I can make the form look like this:

image

Now it's more user-friendly as it's a lot more obvious which button is which. Not that I'd advocate the over-user of icons, but in certain places they can really help out.

To do this we simple added an extra class of "yes" or "no" to the first two buttons. Then in the CSS we added the following rules:

.buttons input.yes {
        background-position: 0 -42px;
}

.buttons input.no {
        background-position: 0 -85px;
}

Make sense? It just moves the sprite image upward the right amount of pixels to show the right icon.

Now, some of you may be thinking the flaw in this is that I have to hard-code the button labels? Well, to get round this I use Computed For Display fields called "ButtonLabelYes", "ButtonLabelNo" and "ButtonLabelSkip". These fields hold the value to show in the buttons.

Inside your WQS you can then do something like this:

if document.Answer(0) = document.ButtonLabelYes(0) then

You can see a working demo of this here. If there's interest in it I'll update the downloadable version of that database. Just let me know.

Comments

  1. Hello,

    interresting but there's a limitation with the button width (and it's value) ...

    With HTML5 you can use a background with the icon and add rounded corners to the button but i think you know that ...

    Using image sprites requires less HTTP requests than several images but i think you know that ...

    So why am i replying to this post ? ...

      • avatar
      • Jake Howlett
      • Tue 20 Sep 2011 09:44 AM

      Good points! Both worth bearing in mind.

      Why are you commenting? Maybe to remind me that people are listening ;-) Also because it's not just me that reads the comments. You're helping enlighten others - not just me.

    • avatar
    • Ferdy
    • Tue 20 Sep 2011 10:05 AM

    Personally, I'd get rid of that blue graphic and code the gradient and rounded corners in CSS3. For IE, you can use the gradient filter.

    The icons are fine, but even those can possibly be replaced with Unicode characters to make it completely image-free.

    I use this quite a lot:

    http://css3button.net/

      • avatar
      • Jake Howlett
      • Tue 20 Sep 2011 02:57 PM

      I respect your opinions and knowledge Ferdy so I'll take it as read that CSS3 is a better option. I'm yet to be completely sold on the idea though. Probably because I've not used it extensively. From what I have seen though I don't think it can reproduce the niceness of an image yet. Not across all browsers in a consistent fashion anyway. See the second link in the main article to the post about creating realistic button images. It talks about adding an inner border and a semi-transparent half-sized rectangle overly on a simple gradient background to make it look truly button-like. While the same thing can probably be achieved with CSS3 I'd imagine it would involve a lot of messy hackery. For now I think I'll stick with using images.

      Hide the rest of this thread

        • avatar
        • Ferdy
        • Tue 20 Sep 2011 03:16 PM

        Jake,

        First of all, both approaches work and are just fine. The image approach is robust and creates a great, consistent result. The small downsides are the image's download size and the inflexibility.

        Still, I'd like to make an attempt on selling CSS3 to you. Here's a few reasons:

        - You don't need hacks. At the most you need a few vendor-extensions in your CSS. They're not pretty, but they're not hacks. In fact, vendor extensions are the standardized way to do this as long as the implementation is not final yet.

        - CSS3 can accomplish the look you are after. I see rounded corners, shadows and an inner gradient. CSS3 can do all of this. The big bonus is that you can change the color, size, rounding, etc without needing to create a new image.

        - If you use vendor extensions you'll be surprised how many browsers you cover. And guess what, it is not going to suck for unsupported browsers. They'll still get a button, a colored one, with a label.

        The last idea is actually the most important concept. The idea that a design needs to look 100% the same across browsers is dated. Better browsers get a better experience, lesser browsers still get a good experience. Unless, of course, you have a client that insists on pixel perfect IE6 support. In that case you make it visible how much such a request costs. I bet they will think a square button is fine.

        To show you how incredibly subtle these differences can be:

        http://www.ferdychristant.com/blog/archive/DOMM-83SSEX

    • avatar
    • Sam
    • Tue 20 Sep 2011 10:09 AM

    Great trick! There's a project I have right now where I can plug this right in. If you could upload the sample database, it would be much appreciated. Thanks, Jake!

  2. or use XPages and add an icon reference in the properties box?

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment:


About This Page

Written by Jake Howlett on Tue 20 Sep 2011

Share This Page

# ( ) '

Comments

The most recent comments added:

Skip to the comments or add your own.

You can subscribe to an individual RSS feed of comments on this entry.

Let's Get Social


About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »

More Content