When structuring your markup there are many paths you can choose to reach the same goal. Most of the times it's a matter of preferences which element you wish to apply on a specific spot. I have my own personal preferences. One of them is preferring BUTTON over INPUT type="submit" elements. Why? Well W3C says it "Buttons created with the BUTTON element function just like buttons created with the INPUT element, but they offer richer rendering possibilities".
It's the rendering that I am after. You can easily apply image replacement techniques to buttons and make your form look good. Most interesting feature is that BUTTON element may have content. I will use that possibility in this tutorial.
So, the goal is to create and style button that can handle variable length so there is no need for later interventions. We'll treat button element as a container and add some markup.
Take a look at the demo | Download zip file
HTML
Here it is:
<button><span><em>Button text</em></span></button>
This is a valid code, and it gives us a lot to work with.
Please note, I am using two child elements instead of only one because I couldn't get rid of some paddings that button preserved. If anyone succeeds in styling with one child element only, please let me know :)
Concept
This concept is probably familiar to you from various navigation tab styling techniques. We have one long background image:

This one is 550px wide. I believe that is more than sufficient for buttons :)
So, we apply this image as a background image of a top element (in this case SPAN), place it to top left and add some left padding. Nested element (in this case EM) have the same background image but placed to top right and with right padding. As the content text grows so will the button.

Height of the button is fixed in my example but you can use similar technique and some more markup and place the same background image to all 4 corners.
To make sure that the text is vertically centered I use line-height property.
CSS
button{
border:none;
background:none;
padding:0;
margin:0;
width:auto;
overflow:visible;
text-align:center;
white-space:nowrap;
height:40px;
line-height:38px;
}
Resetting button's default styling.
button span, button em{
display:block;
height:40px;
line-height:38px;
margin:0;
color:#954b05;
}
Setting child elements. Note that value of height property is different than line-height. That's because I have 2px shadow at the bottom. Line-height vertically centers the text within the button graphic, shadow is excluded.
button span{
padding-left:20px;
background:url(bg_button.gif) no-repeat 0 0;
}
button em{
font-style:normal;
padding-right:20px;
background:url(bg_button.gif) no-repeat 100% 0;
}
Setting backgrounds and paddings for both child elements.
As I mentioned earlier, it would be more elegant if I could use BUTTON and SPAN only, but I couldn' t get rid of BUTTON paddings. Is any find a solution that uses only one child element, please let me know.
Jon Hartmann 4 Mar, 2008
cssglobe 4 Mar, 2008
That padding that remains on button element would even make your suggestion impossible because you wouldn't be able to place the corner image at pixel-precise spot.
hamlet 4 Mar, 2008
not that new ...
http://www.oscaralexander.com/tutorials/how-to-make-sexy-buttons-with-css.html
cssglobe 4 Mar, 2008
If you read carefully, I also mention in the article that the concept might be familiar from various styling techniques.
The trick is to style FORM elements, which anchors are not, unless you add behavior to them.
Andy 4 Mar, 2008
Christoph 4 Mar, 2008
Christoph 4 Mar, 2008
CSS:
button
{
border: none;
background: url(http://cssglobe.com/lab/button/bg_button.gif) no-repeat left 0;
padding: 0 0 0 20px;
margin: 0;
width: auto;
overflow: visible;
text-align: center;
white-space: nowrap;
height: 40px;
line-height: 38px;
}
button span
{
display: block;
height: 40px;
line-height: 38px;
margin: 0;
color: #954b05;
padding-right: 20px;
background: url(http://cssglobe.com/lab/button/bg_button.gif) no-repeat right 0;
}
HTML:
Button without em.
cssglobe 4 Mar, 2008
Sarah 4 Mar, 2008
Sasa Bogdanovic 5 Mar, 2008
Apart from that, if you are not faced with such situation, you present another nice technique from your rich CSS arsenal :)
Pozdrav!
Bramus! 5 Mar, 2008
...
B!
cssglobe 5 Mar, 2008
Dr. 5 Mar, 2008
Belén 7 Mar, 2008
Jonas 10 Mar, 2008
button:hover span,
button:hover em {background: url(otherimage.gif);}
(worx in FF not in IE though.)
Better use js-library for hover fxs imo
Giovambattista Fazioli 10 Mar, 2008
Andree 12 Mar, 2008
pozycjonowanie 13 Mar, 2008
sw 14 Mar, 2008
Web Design Liverpool 17 Mar, 2008
tom 26 Mar, 2008
If you set the width and height of your button using ems or % instead of pixels, your button will resize with the text.
Romi Dumitrescu 24 Apr, 2008
agriturismo lazio 7 May, 2008
thanks :-)
Sam 2 Jun, 2008
I put this code
<a href="sign.html"><button><span><em>Button text</em></span></button></a>
or
<button> <a href="sign.html"><span><em>Button text</em></span></a></button>
When I click on either of these buttons, it does not go to sign page.
Can someone please help me out?
cssglobe 2 Jun, 2008
Sam 2 Jun, 2008
Sam 3 Jun, 2008
Aarabic 11 Jun, 2008
thank you
Frank Ditrich 14 Jun, 2008
But submit button really wan't work correct :(
Cutebaby 14 Jul, 2008
Darren Lovelock 4 Aug, 2008
Starry Nebula 26 Sep, 2008
Raj 31 Oct, 2008
Emil 3 Nov, 2008
Hvala,
Emil
Kane 20 Jan, 2009
<button><span><em class="delete-icon-atleft">icon here</em><em>Button text</em></span></button>
and
<button><span><em>Button text</em><em class="delete-icon-atright">icon here</em></span></button>
or
<a href="#"><span><em class="delete-icon-atleft">icon here</em><em>Button text</em></span></a> and
<a href="#"><span><em class="delete-icon-atright">icon here</em><em>Button text</em></span></a>
?