Styling form buttons

Anyone who’s used the web has encountered buttons in forms. Buttons, as with most form controls, can be a bit tricky to style for consistent look cross browser and cross platform as the operating system often has more to do with how they are rendered than the browser itself. Roger Johansson has delved into this issue in more detail.

What I’m going to do here is present a few different options available for styling your buttons.

There’s two ways to add a button to your HTML: using either the <input> tag or the <button> tag. The most commonly used is probably the <input> although I think, and will show here, how the <button> can be more flexible.

First, let’s look at the two options sans-styling:

<input type="submit" value="Submit" />

<button type="submit" value="Submit">Submit</button>

In most OSes, when you roll over the buttons, there will be a slight colour change, but what else can be done to make them stand out?

I’m going to be using inline styles to illustrate some examples, but ordinarily all these styles would be moved to your stylesheet.

These styles will also apply equally well to both inputs and buttons. If you’ve applied styles to other inputs on your page, you’re going to need some mechanism to override these styles for your input buttons. For browsers, other than Internet Explorer, we can use input[type=submit] { our rules; }, but for full cross browser compatability we either have to use a class on the input in the HTML or use unobtrusive javascript to automatically attach a class to all submit inputs which we then use in the CSS. This is one advantage of using buttons - they have their own tag so can be targetted directly in your stylesheet without the need for any additional classes or IDs.

Changing button colour

We can change the colour of the button’s text and we can make it bold too:

button {
  color: #900;
  font-weight: bold;
}

Making the text bigger

We can, of course, also make the text size much bigger and we could also uppercase the text:

button {
  color: #900;
  font-weight: bold;
  font-size: 150%;
  text-transform: uppercase;
}

We can also change which font is used and the letter-spacing of the text.

Changing the background

All the changes suggested so far deal only with the text and not the background of the button itself. We can change a button’s background or border too, but when this happens, the button will lose its 3D look and become a solid rectangle.

button {
  color: #FFF;
  background-color: #900;
  font-weight: bold;
}

button {
  color: #900;
  border: 1px solid #900;
  font-weight: bold;
}

Hover effects

In his article on styling form widgets, the Man in Blue, Cameron Adams warns against styling buttons in this way and taking away the user’s ‘perceived affordance’ so they will not recognise how they interact with an element, or take longer to do so. It’s certainly a valid point, but a couple of years later, I think web users are more used to different types of buttons and this may not be such a problem as it was.

But to make sure your users understand the button is in fact a button and not just another form input (or any other rectangle on the page), there’s a few things we can do.

In the unstyled example, the button’s background changed colour slightly on rollover. We can do the same thing here:

<button class="btnExample" type="submit" value="Submit"/>Submit</button>

/* CSS */
.btnExample {
  color: #900;
  background: #FF0;
  font-weight: bold;
  border: 1px solid #900;
}

.btnExample:hover {
  color: #FFF;
  background: #900;
}

We could also change the cursor to a hand to make it look more like something that should be pressed:

.btnExample:hover {
  cursor: pointer; /* cursor: hand; for IE5 */
}

As noted in the Man in Blue example above, we can give the button a double-edged border:

.btnExample {
  border: 3px double #FC6;
  border-top-color: #FC9;
  border-left-color: #FC9;
}
.btnExample:hover {
  border-color: #F00 #C30 #C30 #F00;
}

All the :hover examples above require the use of javascript to work in IE6 and lower as those browsers only support :hover on anchors. Some would argue that you shouldn’t mix CSS and javascript to create certain effects, that it should be either one or the other. IE7 is going to support :hover on all elements, so for this type of thing, it’s a case of using javascript as a work-around for incomplete CSS support in older browsers which I think is acceptable.

So far, we’ve just used a solid background-color for the buttons, but we can use background-images just the same.

.btnExample {
  background: #FFC url(/examples/images/buttonbg.png) repeat-x;
}
.btnExample:hover {
  background-color: #900;
  background-position: 0 -24px;
}

Adding images to buttons

So far, we’ve changed the button’s text and background, but we can also add some imagery to the button. Except we can’t use an input; this is where another of the button’s advantages comes into play. Unlike inputs which are inline-replaced elements, buttons can contain other content which can include images.

<button class="btnExample" type="submit" value="Submit"><img src="button-arrow.gif" width="18" height="18" alt=""/>Submit</button>

/* CSS */
button img {
  margin-right: 5px;
  vertical-align: middle;
}

* html button { width: 90px; }

IE adds extra space to the left and right of the content when an image is placed in the button so I’ve used the Holly Hack to give it a width.

Replacing buttons with images

Now, what if we wanted to go a step further and replace the whole button with an image so that we can give it a different shape or use a particular font of our choosing? The most straightforward way to do this is to use an input with type set to image.

<input type="image" src="submit-button-off.gif" alt="Submit details" />

Note the use of the alt attribute to describe what the input does. This is important for people who browse with images off because otherwise they wouldn’t see the button.

This looks like a button but doesn’t have a rollover effect like a non-styled button or the examples we’ve just been looking at. You’ll notice the name of the image is submit-button-off.gif and that’s because there is also a submit-button-on.gif which we can use for creating a rollover effect with image inputs. As the image is actually in the HTML, the only way to change it with user interaction is to use javascript.

We could attach the onmouseover and onmouseout events to the HTML but unobtrusive javascript is preferable to maintain our separation of content and presentation.

The script below is based on one by Christian Watson but I’ve trimmed it back because I’m not targetting all images and not supporting older browsers.

function buttons() {
  var inputs = document.getElementsByTagName("input");
  var i=0;
  for (i=0; i<inputs.length; i++) {
    if(inputs[i].getAttribute('type') == 'image') {
      var image = inputs[i];
      image.offImage = new Image();
      image.offImage.src = image.src;
      image.onImage = new Image();
      image.onImage.imageElement = image;
      if (navigator.userAgent.toLowerCase().indexOf('safari') != - 1) {
        image.onmouseover = function() { this.src = this.onImage.src; };
        image.onfocus = function() { this.src = this.onImage.src; };
        image.onmouseout = function() { this.src = this.offImage.src; };
        image.onblur = function() { this.src = this.offImage.src; };
      } else {
        image.onImage.onload = function() {
        this.imageElement.onmouseover = function() { this.src = this.onImage.src; };
        this.imageElement.onfocus = function() { this.src = this.onImage.src; };
        this.imageElement.onmouseout = function() { this.src = this.offImage.src; };
        this.imageElement.onblur = function() { this.src = this.offImage.src; };
      };
    }
    image.onImage.src = image.src.replace(/-off\./, '-on.');
    }
  }
}
window.onload=buttons;

The script finds all inputs on the page and then determines if they’re of type=image. It then uses the image’s src to create the variables for both on and off states by simply replacing off with on in the image name. Then it’s just a matter of applying the correct state onmouseover and onmouseout; onfocus and onblur are for keyboard users. (Safari also has a problem with onload for off-screen images which is why the conditional statement sets up a different set of functions for it.) Which gives us this (HTML is same as the previous example):

Using CSS image replacement

There is a non-javascript alternative and this is where the <button> comes into play again. As the button can contain other content, we can use an image replacement technique on it. My preferred method is the Gilder Levin Ryznar Jacoubsen IR technique which I’ve used on my article on combining image replacement with Suckerfish dropdowns.

<button type="submit" value="Submit button" class="IR"
  id="IRbutton"><em></em>Submit button</button>

/* CSS */
.IR {
  position: relative;
  overflow: hidden;
  font-size: 1em;
}

.IR em {
  display: block;
  position: absolute;
  top: 0; left: 0;
  z-index: 1;
}

button#IRbutton {
  background: none;
  border: none;
  float: left;
  display: inline;
}

#IRbutton:hover { cursor: pointer; /* cursor: hand; for IE5 */ }
#IRbutton, #IRbutton em { width: 83px; height: 26px; }
#IRbutton em { background: url(/examples/images/submit-button.gif) no-repeat; }
#IRbutton:hover em, #IRbutton:focus em { background-position: -83px 0; }

/* for ie5.x/mac only */
* html>body .IR {
  position: static;
  overflow: visible;
  font-size: 10px;
}
* html>body .IR em { position: static; }
* html>body #IRbutton em { margin-bottom: -26px; }



There’s one notable difference between this and the Gilder Levin Ryznar Jacoubsen method and that’s that the background-image isn’t attached to the parent element, the button, as well. To do so causes the rear image to be visible by a few pixels behind the front image.

The float: left and display: inline on the button itself are also required by Opera 8 & 9 to ensure that they render the image at all (v9) and in the right place (v8) (thanks to Paul O’Brien for the tip).

The actual image for the button contains both on and off states and looks like this:

Using the button’s background-position property we can move the off state out of view and replace it with the on state when the image is hovered over (see above for the extra help that IE needs on this). With images turned off, the user will still see the button’s text making this a better option than image replacement methods that move the text off-screen.

So we can use images that look like buttons but still have our own style about them at the same time as retaining the user interaction element by enabling change of state when the mouse is hovered over the button or it is tabbed into using the keyboard.

Update

Mon, Feb 18, 2008 @ 9:41 am

I’ve begun using JQuery on this site recently and as such have replaced the script above with this:

$(document).ready(function() {
	$('input[type="image"]').hover(
		function () { $(this).attr("src", $(this).attr("src").split('-off').join('-on')); },
		function () { $(this).attr("src", $(this).attr("src").split('-on').join('-off')); }
	);
});

Browse by tags:

Tags: , , , , , ,

Share this article:
  • Twitter
  • FriendFeed
  • del.icio.us
  • Digg
  • StumbleUpon
  • Facebook
  • Reddit
  • Sphinn

Subscribe to this site for regular updates

62 responses to Styling form buttons. Add your own.

Comments

  1. 1

    There’s simpler way to do images with buttons, and that’s to include a background image on the css class as in
    .buttonStyle {
    padding:0px 0px 7px 0px;
    background-color:#FFF;
    background-image:url(/images/formButton.jpg);
    width:106px;
    height:31px;
    /* image is 106 by 31 pixels */
     }

    then simply add the class to the submit or button input control.

    regards,
     larry

  2. 2

    Hi Larry,
    Yes that’s true and in cases where the image is purely decorative, it’s probably a better option to do it that way.
    It’s still worth pointing out though that the button tag can contain other content (e.g. <em> or <strong>).

  3. 3

    What I’ve been doing lately is styling padding, color, background-color, and cursor (pointer) for static, hover, and focal states, and I’ve also been applying border. For borders I’ve been using a 2-3 px outset, and I use that static and hover states, but then for focus I’ve been changing it to an inset border. I like the interactive response it gives you get when “pushing” the button.

  4. 4

    Yeah, that’s a nice idea, Mike.

  5. 5

    I’m trying to facilitate that a css file is able to override the text (value) content of a ‘button’ (i.e. input) and instead of this, display an image. In other words, if the css doesn’t implement an image it should display the (original) text value in the html.
    I’d really appreciate the help on knowing how to do this? I’m sorry if this is a very basic question.

  6. 6

    Hi David,
    you might need to explain that a bit better. Under what circumstances will the CSS not implement an image?

  7. 7

    Isn’t that done by specifying input type=”image” and applying the alt attribute (which is okay to use on inputs in lieu of the label element)… or am I missing the point?

  8. 8

    hey John, you forgot to add a semicolon at end of a css line:

    .btnExample:hover {
    background-color: #900
    background-position: 0 -24px;
     }

  9. 9

    I did too. Sorry about that. It’s fixed now. Hope it didn’t result in too much time in frustration trying to work out why something wasn’t working.

  10. 10

    Does anyone know how to get inout:hover to work for ie, I can get a background img with a hover background img on inputs using css in Firefox but nthis doesnt work in IE? Has anyone got around this?

  11. 11

    Keiran, this article should answer your query about :hover not working in IE.

    If you use the javascript approach as described above it shouldn’t be an issue.

  12. 12

    Wow, fantastic article. I have been looking around for something like this for a while.

    Well done.

  13. 13

    Wow, you cut out any examples of actual code. thats annoying. let me try again.

    I am experiencing a strange IE bug when working with input type=submit although i think this affects buttons as well.

    The issue i have is that IE adds left and right padding to buttons. the padding is dependant on the length of the text so if i have two buttons one on top of each other with different lengths of text they will look wierd because the text starts at different points.

    Any ideas how i can get around this without specifying a width

  14. 14

    Hi Simon,

    If you have different lengths of text but want buttons to be the same width, then your only solution is to apply a width to them.

    It’s the same with most elements containing text - paragraphs, for instance. Without a specified width, the paragraphs will appear a different length if they have a different amounts of words.

    IE does seem to add more padding around text in buttons so you might like to use an IE-only filter or conditional comment to reduce that padding (while leaving it alone in other browsers).

    And about your HTML being removed: I didn’t do it personally ;) If you look in the reply box, you’ll see a list of permitted HTML tags.

  15. 15

    You say the hover stuff will only work with javascript in IE6, yet I’m struggling to find any mention of what javascript is needed in the article. I’ve copied and pasted your first hover example directly to a clean page and when I hover over the button on this new page there are no hover effects applied to the button, yet it works in your article. Can you explain what I’m missing? Thanks

  16. 16

    Hi Jon,

    There is a link to a javascript solution (otherwise known as ‘behaviours’) mentioned in the article: whatever:hover.

  17. 17

    ok thanks. I’m looking through that page now. I didn’t realise that this tyssendesign page used the same technique.

    thanks again :)

  18. 18

    Wonderful, the adapted Christian Watson script works like a charm, just what i was looking for. Thanks!

  19. 19

    I love the real-time preview on this comment box. Brilliant. I’m going to have to steal the idea :)

  20. 20

    GOOD WORK AH

  21. 21

    Good site

  22. 22

    Thank you so much for this. I’ve just been working at this problem myself and you’ve helped fill in a few missing blanks.

    Signed
    A very happy coder

  23. 23

    hi

    For some reason the image replacement button does not seem to work in IE6 for me, i have used the code exactly how you have it and cant get it to work, any ideas as it works fine on your page in IE6.

    cheers

  24. 24

    Ceri, it’s impossible to say without seeing your code or a link to the page.

  25. 25

    John, here is a link to a test page, with just the code in question.

    http://www.test-area.co.uk/1stsecurity/test.htm

    thanks in advance

  26. 26

    Ceri, if you read back through the article you’ll find:

    All the :hover examples above require the use of javascript to work in IE6 and lower

    This applies to all the examples where :hover has been applied to the button to effect a change.

  27. 27

    great thanks very much, will teach me to read things properly!

  28. 28

    Excellent! Love this article!… :)

    Thanks!..

  29. 29

    Thank you for taking the time to make this resource!

  30. 30

    AAAAAA ha !!!

    Really really a useful tutorial.

    Thanks a lot.

  31. 31

    Hi, my simple solution:

    CSS:

    #button {
    display: block;
    width: 89px;
    height: 21px;
    margin: 0px auto;
    background-image:url(‘/img/search.gif’);
    background-position:left top;
    background-repeat:no-repeat;
    }
    #button input:hover{
    background-image:url(‘/img/search_hover.gif’);
    background-position:left top;
     background-repeat:no-repeat;

    and trasparent gif in HTML:

  32. 32

    What happens if I have a form with few buttons on it and if an user hovers over a button I would like to have a window pop up to explain what the button will do if clicked. The button has a “control tip text” property (on the OTHER tab) where you can add the bubble comments. I don’t know if you can affect the timer.

  33. 33

    Istra, what you’re after is really outside the scope of this article, but if it were me, I’d be thinking that if your buttons need extra explanation that possibly you’re using buttons for inappropriate uses. For the sort of functions that buttons are used for, you should be able to describe that function with the text of the button itself.

  34. 34

    I tried this approach under IE 8.0.6001.18783. I was able to style the text boxes which succeed under all major browsers. And the buttons style under every browser except IE. Any help out there? The following is what I have tried:

    input.button (
    border: 0px solid #85b1de;
    background-image: url(‘http://ezhousefixes.com/Images/CSS%20Resources/button-start.png’);
    background-repeat: repeat-x;
    height: 18px;
    color: #ffffff;
     }

    Above, where I put input.button I have simultaniously used button, input[type=”button”], input:button, input->button, input button, input#button

    This is the last object on my site that needs to be styled and I hope someone out there can help me anyone. Thank you for any thoughts :)

  35. 35

    Hi Brandon, I’d need to see your HTML too.

  36. 36

    Got it to work! uuuwhooo! i’ve used the jquery and this
    input type=”image” src=”http://mydomain/folder/buttons/submit-off.gif” alt=”Submit details” />

    Except now my hover image is not working! what am i doing wrong please.

  37. 37

    Do i need to make any changes to the javascript as it doesn’t seem to be working. sorry i’m a noob and don’t understand javascript.
    thanks
     jim

  38. 38

    Jim, you really need to post these sorts of questions to a forum like CSSCreator so that you can post all the relevant code and get the benefit of a variety of different people who have expertise in this area to help you.

  39. 39

    Thanks a lot for the tutorial, very helpful.

Pingbacks

  1. 1

    links from TechnoratiStyling form buttons — Tyssen Design

  2. 2

    […] mis bookmarks Styling form buttons varias tecnicas para decorar botones en formularios […]

  3. 3

    […] » Styling form buttons — Tyssen Design […]

  4. 4

    […] Styling form buttons - Tyssen Design […]

  5. 5

    […] Styling form buttons - Tyssen Design Push my button - Digital Web Magazine […]

  6. 6

    […] Styling form buttons - Tyssen Design […]

  7. 7

    […] Styling form buttons — Tyssen Design […]

  8. 8

    […] Your page is on StumbleUpon […]

  9. 9

    […] - Styling form buttons — Tyssen Design css buttons forms […]

  10. 10
  11. 11

    […]Styling form buttons — Tyssen Design[…]

  12. 12

    […] Styling form buttons — Tyssen Design […]

  13. 13

    […]Styling form buttons – Tyssen Design[…]

  14. 14

    […] Styling Form Buttons […]

  15. 15

    […] 【海外記事】CSSによる、フォームのサブミットボタンのスタイリング […]

  16. 16

    […] Buttons for Forms Here is a web site for Styling Form Buttons Using CSShttp://www.tyssendesign.com.au/articles/css/styling-form-buttons/ Posted by Donnaj […]

  17. 17

    […] Element shows the differences between links and buttons and explains how to style buttons easily.Styling Form Buttons covers the basics of styling buttons, with many examples.Beautiful CSS Buttons With Icon Set shows […]

  18. 18

    […] Styling Form Buttons covers the basics of styling buttons, with many examples. […]

  19. 19

    […] Styling Form Buttons covers the basics of styling buttons, with many examples. […]

  20. 20

    […] Styling Form Buttons covers the basics of styling buttons, with many examples. […]

  21. 21

    […] Styling form buttons […]

  22. 22

    […] Styling Form Buttons […]

  23. 23

    […] Styling Form Buttons covers the basics of styling buttons, with many examples. […]

Feed for this post's comments


Required indicates required field.
Email will not be published

You can use these tags in your reply:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Leave a Reply

Contact details