Take the 2-minute tour ×

I'm trying to elegantly solve a styling issue with some buttons and images. My goal is to have buttons that look like the following:

(Hacky mspaint mockup)

Button Example

However, I have a set of criteria I'd like to meet:

  • I also need to be able to have the icon image exist as a button alone, with no text (i.e. the button background is the icon image and the button width/height = icon image width/height).
  • The icon-only button needs to support :hover states that change the background icon.
  • The text buttons need to support the gradient background changing on :hover, but the icon itself does not have to change.

I have both the icon image and gradient image available to me in a vertical CSS sprite image.

Currently, I can only think to do this with separate sets of styles for the text buttons and icon-only buttons, along the lines of:

<!-- text-button -->
<!--   button.text-button would have gradient background and border -->
<!--   button.text-button:hover would change to the hover gradient -->
<!--   .icon would have the icon background (icon border is included in image) -->
<button class="text-button">
    <div class="icon-delete">Button Text</div>

<!-- icon-only button -->
<!--   button.icon-button would have the specific icon image background -->
<!--   button.icon-button:hover would change to the hover state background -->
<!--   button styling is different than .text-button, since icon border is included in image -->
<button class="icon-button-delete"></button>

I don't particularly like using the inner <div> for the text button, since it seems to add more markup that might be unnecessary. It also makes it so that if I wanted to go back later and add text to a button, I'd have to change several components instead of just changing the button class. It also means that I probably have to define the image positions for my icon sprites for several different combinations of button/div styles, which isn't DRY.

To summarize my question: How can I do this with a single top-level style on the <button>, rather than using nested elements or separate styles for the icon- vs text- buttons? It doesn't necessarily have to be a <button> either, it could be any element if it accomplishes this elegantly.

I don't really need a full code sample, just a suggestion for how it might be accomplished best.

share|improve this question
It seems as though this might not be possible to do easily. A simple solution is to just get rid of the gradient and use a solid background color. –  Rob Hruska Jun 25 '10 at 20:36
Additionally, this looks possible with CSS3 and multiple background support. –  Rob Hruska Jun 25 '10 at 21:21
add comment

4 Answers

You can reduce the markup a bit:

<div class="button">
    <a class="yourIcon">Button Text</a>

.button gets the gradient image.

.yourIcon can then get an icon for a background if desired.

share|improve this answer
add comment

Personally, I'd just use an <img> with a transparent gif and a CSS background-image instead of your icon div. And a span for the text. For the text-free version of the button, just leave out the span and adjust the button class.

I've built a crude demonstration here: http://jsfiddle.net/TTyPZ/3/

Version 2: http://jsfiddle.net/z9pD9/1/

share|improve this answer
Thanks for the answer. +1 for taking the time to provide the code sample. This is definitely an alternative that will work, although it doesn't necessarily address my plea of a 'single, top-level style'. –  Rob Hruska Nov 12 '10 at 21:03
I like a challenge. Is this getting closer? jsfiddle.net/z9pD9/1 –  stevelove Nov 12 '10 at 21:37
add comment

You could use simplify it at max: just use gradient as background and insert insert another tag with icon as background inside, use css vertical-align property (it accepts % values) to place the icon properly aligned to text.

instead of using div tags consider using <b> tag, ir saves ytou some bytes and it is s google technique by the way.

hope this helps

share|improve this answer
I'm not quite following you here - what you're suggesting seems to be similar to what I gave in my example, which is what I'm trying to avoid. Can you elaborate? –  Rob Hruska Jun 25 '10 at 20:18
add comment

Can you just create 2 separate button elements and use absolute positioning to get the icon button on top of the big button?

share|improve this answer
add comment

Your Answer


