Cross-Browser Rounded Buttons with CSS3 and jQuery

So here’s the scenario: I was tasked with replacing several dozen Photoshop-generated rounded buttons for a larger site with an HTML/CSS/JS equivalent. Prior, any time anyone wanted to change text on a button (and it seemed to happen often), a graphic designer had to fire up Photoshop, modify a file, adjust for size, output an image, and pass that file off to the person building the page. It was an involved process for something that should have been simple.

So let’s make it simple!

Right away I knew that I wanted to present as simple a solution for the developer as I could. I didn’t want to force them to use tons of extra markup in their HTML to pull this trick off. This was a piece of cake in modern browsers, as you’ll see in a moment. Unfortunately, this site also has a large IE user base, so I needed to account for less-modern browsers as well.

Border-Radius for Those Who Can

I decided I wanted to use border-radius for the rounded buttons for any browsers that could support it. I also decided that I wanted to create a single class, “button,” for any buttons, and it should work more-or-less the same on anchor tags, button tags, and “submit-type input tags.

In short, my HTML should be as simple as this:

1
2
3
<a href="link.html" class="button">A Button!</a>
<button class="button">Also A Button</button>
<input type="submit" class="button" value="Das Button" />

Input and button tags are admittedly tricky, as I’ve mentioned elsewhere. For this exercise we’ll ignore most of that and not worry about pixel-perfect results. Really, really close is good enough for me on this one.

My CSS for those happy modern browsers looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.button {
	display: inline-block;
	line-height: 1;
	padding: 7px 10px;
	text-decoration: none;
	font-weight: bold;
	color: #fff;
	background-color: #39c;
	-moz-border-radius: 5px;
	-webkit-border-radius: 5px;
	-khtml-border-radius: 5px;
	border-radius: 5px;
}
input.button, button.button {
	border: 0px none;
}

The display: inline-block makes our button behave like a block-level element (width, height, padding and the rest), while still staying “in line”. Our border-radius is set at the bottom: 5px, all around. We use vendor-prefixed rules first, for Mozilla, Webkit, and Khtml browsers. Then we finish with the “standard” border-radius rule, which is currently supported by Opera 10.5. We also have a separate rule to remove the default border on input and button tags. The rest is just text and color styling.

And just like that, we have nice rounded buttons that work in Safari, Chrome, Firefox and even the latest version of Opera! So who missed the party bus? Our old friend Internet Explorer, of course (and Opera browsers older than two months, as well). The client wasn’t comfortable giving those users square buttons, so I had to do something, and step one of that something is being able to tell which browsers can’t handle border-radius.

Sniff the Diff

This is where that test for border-radius support that I built last week suddenly comes in handy. I simply include a small jQuery function, run the test, and I can now tell whether or not the browser supports border-radius (vendor prefixed or otherwise). If you missed my article last week, I’d be sure to check that out before going any further.

With the help of my $.support.borderRadius object, I can now write some jQuery to treat those browsers that don’t support border-radius differently.

Modify the DOM

There’s no good way to fake rounded corners in Internet Explorer without resorting to images. However, that doesn’t mean we’re stuck with creating a one-size-fits-all button image and dealing with inflexibility. Really, the only part of the button we’re worried about changing is the borders. So let’s just worry about them!

We’re going to use jQuery to create a structure that looks like this:

1
2
3
4
5
6
7
<div class="buttonwrap">
	<div class="tl"></div>
	<div class="tr"></div>
	<a href="link.html" class="button">Our Button</a>
	<div class="bl"></div>
	<div class="br"></div>
</div>

The buttonwrap div acts as a container for the rest of our elements, and will be relative positioned (but not moved) to turn it into a positioned parent, letting us move objects around inside it. The four corner divs are then absolutely positioned on top of our button and moved to the four corners (“tl” for top-left and so on).

Here’s the jQuery that gets it done:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
jQuery(function() {
	jQuery.support.borderRadius = false;
	jQuery.each(['BorderRadius','MozBorderRadius','WebkitBorderRadius','OBorderRadius','KhtmlBorderRadius'], function() {
		if(document.body.style[this] !== undefined) jQuery.support.borderRadius = true;
		return (!jQuery.support.borderRadius);
	});
});
$(function() {
	if(!$.support.borderRadius) {
		$('.button').each(function() {
			$(this).wrap('<div class="buttonwrap"></div>')
			.before('<div class="corner tl"></div><div class="corner tr"></div>')
			.after('<div class="corner bl"></div><div class="corner br"></div>');
		});
	}
});

If the browser doesn’t support border-radius, we wrap our buttons in the buttonwrap div, then insert our four corner divs. Admittedly, we could have put all the corners in a row, but I like the idea of putting them in the same order they’ll appear visually. And sure, it’s five extra divs in our DOM… but they’re not in our HTML. I’m comfortable with that trade-off in this situation.

Now we need just two more pieces: the CSS to position everything properly, and the image that will let us fake our corners. Let’s deal with the image first.

One Image to Round Them All

You’ll be amazed at how simple this turned out to be (at least, I was!). We only need one teeny tiny image to round all four of our corners.

In my situation, I was dealing with dozens of buttons, some of different colors, but all on a white background. Because of that, I realized what I needed was a transparent PNG: white on the outside “background” area, and transparent on the inside to let my CSS button background color show through. And because my corners were all rounded the same amount, what I really needed in each corner was a quarter of a circle.

So what I did was open up Photoshop and create a 10px by 10px image. Then I gave it a white background, used the elliptical marquee tool to draw a circle in the center, and then deleted the center out (no feathering, but with anti-aliasing).

If you only had a single button color but multiple background colors, I’d still approach it the same basic way. I’d simply “select inverse” after creating my circle, delete the outside instead of the inside, and proceed the same.

Once I saved the image as a 24-bit PNG, my total file size was 182 bytes. If I were using a fancier image program like Fireworks, I probably could have gotten the image size even smaller. And admittedly, if you want the transparent PNG to work in IE6, you’ll need to use a PNG fix of some sort. But that’s outside the scope of this particular article. Google will assist in this one.

Now, using the power of CSS background positioning, I can show just a quarter of that image in each of my corners. Here’s my final IE-friendly CSS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.buttonwrap {
	display: inline-block;
	position: relative;
	zoom: 1;
	*display: inline;
}
.corner {
	position: absolute;
	width: 5px;
	height: 5px;
	background: transparent url(images/corner.png) no-repeat 0 0;
}
.tl { top: 0; left: 0; background-position: left top; }
.tr { top: 0; right: 0; background-position: right top; }
.bl { bottom: 0; left: 0; background-position: left bottom; }
.br { bottom: 0; right: 0; background-position: right bottom; }

Note: The “zoom” and “*display” rules above are a necessary hack that causes IE7 to mimic the inline-block property (which it does not implement correctly).

So that’s it! Here’s a working example for you to try out.

Limitations

I’ll admit it: this solution isn’t perfect. Just pretty darn convenient for my situation. Some limitations include:

  • IE6 requires a PNG fix, as I mentioned earlier.
  • You’re stuck with either one button color, or one background color, per image. Additional classes and images could expand this, though.
  • Corners are all the same radii.
  • It’d be tougher (though not impossible) with a border on the button.
  • It hasn’t made me coffee (yet).

However, I expect this will be useful to someone else. I’ve already found two uses for it since I wrote the original code!

34 Comments

  1. On April 23, 2010
    3:12AM

    Paweł P. said:

    In the right time I read
    this article. Good work (saved)

  2. On April 23, 2010
    8:03AM

    Matthieu Desjardins said:

    Love this!
    I specially appreciate the cross-browser (even the dreaded IE6) compliance. Too many poeple these days don’t bother about this anymore and just say “The hell with them!”.
    Good work!

  3. On April 23, 2010
    9:03AM

    Vel said:

    This isn’t simple. I don’t see a reason to use jquery. This can be done just with <a href=”#” rel=”nofollow”>Link</a> and with one image.

  4. On April 23, 2010
    9:30AM

    Rob Glazebrook said:

    Hi Vel,

    (I fixed your comment code so it shows up properly, so I removed the other comments).

    You could use just one image, as long as you were okay with all of your buttons being exactly the same size. That wasn’t so in my case. Our buttons varied in both height and width, so I needed a flexible solution that could work in dozens of different places (including places that we hadn’t even thought up yet!).

  5. On April 23, 2010
    10:13AM

    Vel said:

    Well, the code I’ve posted isn’t one that is shown in my comment :)
    I’m talking about Sliding Door technique and here is tutorial how to make this with only one image http://kailoon.com/css-sliding-door-using-only-1-image/

  6. On April 23, 2010
    10:21AM

    Rob Glazebrook said:

    Ah, thanks for the link, Vel.

    That is a similar technique, but not quite the same concept. Dimitar’s technique would work for elements that expanded horizontally, but not vertically. And it still requires extra markup: you need an anchor tag and a span tag to pull it off.

    I consider mine to be a nice alternative, because for 75% of the people that visit the site, they get rounded corners on all their buttons with zero images and no extra markup at all. But the other 25% still get rounded corners, with 1 (very, very small) image.

    I’m not saying that the technique you linked to is bad: it looks very clean and well put together! It’s a different solution for a different problem. :)

  7. On April 23, 2010
    10:28AM

    Vel said:

    What I wanted to say, is that I wont use jquery for something that can be done with css only, but you are right that your technique is good for buttons/links, which will go on 2+ rows ;-)

  8. On April 23, 2010
    1:43PM

    Top Wordpress Themes said:

    Your solution looks pretty good. However, I think it is more efficient to simply create a button class using CSS. This way it is super easy to change the text. And than you can always make a new button img for it….Or at least this is how I always do it. :)

    ex:

    .btn{ display: block; width: 150px; height: 50px; line-height: 50px; background; image(btn.png); text-align: center; padding: 0px 5px; text-shadow: 0px 1px #000; color: #FFF;}

    Click Here

  9. On April 23, 2010
    1:44PM

    WPExplorer said:

    Oh yea, I forgot the div’s wont show up. Haha

  10. On April 23, 2010
    2:08PM

    Rob Glazebrook said:

    Perhaps I don’t understand what you’re getting at, WPExplorer… my solution also uses a single class of .button. At least, it does for everything not-IE.

    It looks like your one-class-fits-all idea would work fine as long as you don’t need buttons of different sizes, which is sort of my entire point. Let’s say you have one button that says “Go” and another that says “Click Here to Access Your Free Content”, and you want to use the same button class for each. Now you’re stuck either making your button absurdly huge for “Go” or editing your button text on the longer one to fit your background image width.

    My whole goal was to create something that allowed for massive button-size flexibility, that offered rounded corners, that worked cross-browser, and that kept my source clean.

  11. On April 25, 2010
    10:28AM

    shin said:

    I checked it with IE7, it does not show rounded corners on the top right and bottom right. Demo on IE6 does not work either.

  12. On April 27, 2010
    11:47AM

    Rob Glazebrook said:

    Thanks for pointing that out, Shin. I’ve added a tiny hack to the CSS to account for IE7′s problems. I’d forgotten that IE7 doesn’t play well with inline-block. Luckily, there’s a two-line workaround!

    I don’t have a copy of IE6 installed here. Can anyone test the demo against IE6 and let me know of any problems?

  13. On April 27, 2010
    4:13PM

    Francis Adu-Gyamfi said:

    Even simpler solution for IE, which should help complete your solution without the need for any javascript at all.

    http://aext.net/2010/04/css3-ie-support/

  14. On April 27, 2010
    4:19PM

    Rob Glazebrook said:

    Excellent find, Francis! Thanks for sharing. I’m going to download this and play around.

  15. On April 28, 2010
    2:36PM

    Deluxe Blog Tips said:

    If use jQuery, I would like to use a plugin to make rounded corners without images. This’s better because we don’t have to concern about PNG fix for IE6. Btw, your solution is also a good one.

  16. On May 04, 2010
    6:19PM

    kirolos hany said:

    this is wonderful tutorial .. i read it 3 times and get a fantastic results and sure i put a
    copy of this lesson on my here http://www.learnanyway.blogspot.com

  17. On May 13, 2010
    4:33PM

    Todd J. List said:

    I just found your site today, and it now has the #2 spot in my list of CSS resources (an A-Z list of all the CSS properties is first). You cut a lot of time out of my learning curve.

    Thank you.

    As for IE users, I say give them the sharp corner if they can’t take a radius. It’s still better than a sharp stick in the eye. ;) Ow.

  18. On June 01, 2010
    1:58PM

    Oli said:

    IE6 PNG fix is NOT compatible with CSS background positioning.

  19. On June 17, 2010
    12:33PM

    madhu said:

    really a nice stuff for the beginners, thanks very much for the very good posts on CSS

  20. On June 29, 2010
    11:56PM

    Damar said:

    a very good innovation ^_^ nice

  21. On July 03, 2010
    10:34PM

    Ahmad said:

    Wow ,ive found at last.thanks for sharing

  22. On July 08, 2010
    11:43PM

    damu said:

    Just happily subscribed to your feed. Good articles with gr8 site.

  23. On July 11, 2010
    10:50AM

    rehabilitasyon said:

    Hi, I’m beginning to learn css program. Write your thank you letter will help me a lot of work.

  24. On July 16, 2010
    9:37AM

    Javier murcia said:

    Nice article.I have to work with this tutorial

  25. dhanasekaran said:

    your codes will not work in IE..kindly check and update to us..

  26. Chris said:

    I use the same thing, but don’t rely on images, I use http://css3pie.com/ to achieve rounded corners, graident and drop shadow. Works great with ie 6-8 and for the most part requires no extra mark up to make IE play nice…

  27. Brett Widmann said:

    This is a really helpful article. I like all the examples and code sets you give. Thanks for sharing.

  28. dave said:

    Great work, bookmarked!

  29. Plippie said:

    Why not use CSS3Pie ?
    http://css3pie.com/

  30. Cgbaran said:

    Great tutorial thanks

  31. dpm said:

    Has anyone actually tested this in IE6?

    It seems like a large fail from what I see….

  32. On April 08, 2011
    7:58AM

    Bughy said:

    This is great Rob. It works great on some versions of IE!
    @dpm : I test it, and not working good. But serios now…how many people do you think they still use IE6?? It’s old.

    One again: Nice JOB Rob!!!

  33. On July 14, 2011
    8:25AM

    Narendran said:

    But the rounded corner for the button is not working in IE8… Hv a look on it,& get back me.

    Add ie.htc file for this

    Awaiting with regards,
    Narendran,
    9487693560,
    Tweet me @MyNaren89.

  34. Maciej Egermeier said:

    There is a problem with this buttons on IE. If you turn on overflow:scroll on DIV where buttons are placed, DIV is scrolling content but buttons are in the same position :/

36 Responses Elsewhere

  1. On April 27, 2010
    10:57AM

    Bookmarks for April 27th from 14:42 to 14:42 | Travis' Blog said:

    [...] Cross-Browser Rounded Buttons with CSS3 and jQuery – ‹Previous Post Bookmarks for April 26th from 16:03 to 16:03 [...]

  2. On May 26, 2010
    3:32AM

    20 Awesome jQuery Enhanced CSS Button Techniques - Speckyboy Design Magazine said:

    [...] Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  3. On May 31, 2010
    10:19PM

    jQuery Enhanced CSS Button Techniques said:

    [...] Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  4. ” 20+jQuery增强型CSS按钮– HTML5,CSS3,WEB前端设计开发资讯站 said:

    [...] Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  5. Complete Toolbox: 55 CSS Menu And Button Coding Tutorials » abdie.web.id said:

    [...] 21. Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  6. On July 06, 2010
    11:52PM

    Complete Toolbox: 55 CSS Menu And Button Coding Tutorials | CG Stream said:

    [...] 21. Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  7. Complete Toolbox: 55 CSS Menu And Button Coding Tutorials said:

    [...] 21. Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  8. Complete Toolbox: 55 CSS Menu And Button Coding Tutorials | TechFleck said:

    [...] 21. Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  9. 55 CSS Menu And Button Coding Tutorials « FED视野 said:

    [...] 21. Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  10. 40 jQuery and CSS3 Tutorials and Techniques - Speckyboy Design Magazine said:

    [...] list of items and you will use jQuery to make sure IE understands it too. View the Demo →Cross-Browser Rounded Buttons with CSS3 and jQueryView the Demo →CSS3 & jQuery Image Gallery and Slider TutorialsAn Awesome CSS3 Lightbox [...]

  11. On July 13, 2010
    10:58PM

    40 jQuery and CSS3 Tutorials and Techniques « Vision said:

    [...] Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  12. 20 Must Learn Button Tutorials in jQuery and CSS | blueblots.com said:

    [...] Cross Browser Rounded Buttons [...]

  13. The Ultimate Roundup of 55+ CSS3 Tutorials said:

    [...] 22. Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  14. The Ultimate Roundup of 55+ CSS3 Tutorials | luLUXE said:

    [...] 22. Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  15. The Ultimate Roundup of 55+ CSS3 Tutorials « qeqnes | Designing. jQuery, Ajax, PHP, MySQL and Templates said:

    [...] 22. Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  16. 40 jQuery and CSS3 Tutorials and Techniques « Nap5teR said:

    [...] Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  17. Css ile buton yapma | web tasarım ve internet magazin said:

    [...] buton örnekleri 2 Harika buton örnekleri 3 Harika buton örnekleri 4 Harika buton örnekleri 5 Harika buton örnekleri 6 Harika buton örnekleri 7 Harika buton örnekleri 8 Buton örnekleri daha da çoğaltılabilinir [...]

  18. The Ultimate Roundup of 55+ CSS3 Tutorials | LionWebMedia.com said:

    [...] 22. Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  19. Css ile buton yapma @ İnternet Magazin said:

    [...] buton örnekleri 2 Harika buton örnekleri 3 Harika buton örnekleri 4 Harika buton örnekleri 5 Harika buton örnekleri 6 Harika buton örnekleri 7 Harika buton örnekleri 8 Buton örnekleri daha da çoğaltılabilinir [...]

  20. 70 Must See CSS3 Tips, Tricks And Tutorials said:

    [...] 34. Cross- Browser Rounded Buttons With CSS3 And jQuery [...]

  21. 70 Must See CSS3 Tips, Tricks And Tutorials « Spartan Pixel | News and much more said:

    [...] 34. Cross- Browser Rounded Buttons With CSS3 And jQuery [...]

  22. Dicas, Truques e Tutoriais para utilizar CSS3 » vitorbritto – Visual and Interaction Design said:

    [...] 34. Cross- Browser Rounded Buttons With CSS3 And jQuery [...]

  23. CSS3 Tutorials to Brighten Up Your Day - Noupe Design Blog said:

    [...] Cross-Browser Rounded Buttons with CSS3 and jQuery In this tutorial, a cross-browser with rounded buttons will be created with the help of CSS3 and jQuery: [...]

  24. Diar's Playground» CSS3 Tutorials to Brighten Up Your Day said:

    [...] Cross-Browser Rounded Buttons with CSS3 and jQuery In this tutorial, a cross-browser with rounded buttons will be created with the help of CSS3 and jQuery: [...]

  25. Css ile buton yapma « furkanknyl said:

    [...] buton örnekleri 2 Harika buton örnekleri 3 Harika buton örnekleri 4 Harika buton örnekleri 5 Harika buton örnekleri 6 Harika buton örnekleri 7 Harika buton örnekleri 8 Buton örnekleri daha da çoğaltılabilinir [...]

  26. On April 30, 2011
    12:55PM

    CSS3 Tutorials to Brighten Up Your Day - desmaksolutions.com | desmaksolutions.com said:

    [...] Cross-Browser Rounded Buttons with CSS3 and jQuery In this tutorial, a cross-browser with rounded buttons will be created with the help of CSS3 and jQuery: [...]

  27. 150 Excellent CSS3 Tutorials To Make You A Stylish Web Designer said:

    [...] Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  28. 100 Great CSS3 Tutorials | Stylish Web Design said:

    [...] Intricacy of Simplicity: CSS3 The State of CSS3 in Email Templates Create Beautiful CSS3 Typography Cross-Browser Rounded Buttons with CSS3 and jQuery How to Dynamically Highlight Content Like Wikipedia Using CSS3 CSS3 Glow Tabs css3 border image How [...]

  29. 10 jQuery Enhanced CSS Buttons | jQuery4u said:

    [...] how to make a cross-browser rounded buttons with CSS3 and jQuery in this tutorial. Source #dd_ajax_float{ background:none repeat scroll 0 0 #FFFFFF; border:1px solid #DDDDDD; float:left; [...]

  30. CSS3 Tutorials to enhance your work | Dreamincolor said:

    [...] Cross-Browser Rounded Buttons with CSS3 and jQuery So let’s make it simple! [...]

  31. 20 Beautiful jQuery Enhanced CSS Button | ExceptionHandle.com said:

    [...] Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  32. Tips and Tricks To Imrove jQuery | DesDevWeb said:

    [...] Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  33. 36个精彩的CSS3动画[Demo演示] | 色落De Alex said:

    [...] Your Images Into Polaroids with CSS3 14.Beautiful Looking Custom Dialog Box With jQuery and CSS3 15.Cross-Browser Rounded Buttons with CSS3 and jQuery 16.CSS3 DropDown Menu 17.CSS3 Search Form 18.Pure CSS Coke Can 19.CSS3 Music Player Menu 20.Elastic [...]

  34. [转载] 36个精彩的CSS3 动画demo演示 | 天豪军尚 said:

    [...] 15. Cross-Browser Rounded Buttons with CSS3 and jQuery [...]

  35. CSS3 Tutorials « CSS Tips said:

    [...] Cross-Browser Rounded Buttons with CSS3 and jQueryIn this tutorial, a cross-browser with rounded buttons will be created with the help of CSS3 and jQuery: [...]

Leave a Comment