Most of the time when designing your site navigation you’ll turn to an image to give it that something extra. However images add weight to a web page and make additional http requests leading to longer load times. Ever since I began developing websites, I’ve looked for ways to replace images with code. Today I want to share a simple way to style navigation buttons sans images and using css only.
Note: If you decide not to use the technique below and prefer to use images for your nav buttons I suggest using css sprites. If you’re unfamiliar with css sprites have a look at these posts to learn how to use them.
- The Mystery Of CSS Sprites: Techniques, Tools And Tutorials
- CSS Sprites: Image Slicing’s Kiss of Death
- CSS Sprites2 – It’s JavaScript Time
Final Navigation Bar Preview
Before we begin let’s take a look at where we’re going. Here’s an image of what our final navigation bar will look like as well as an image of how it will look when mousing over one of the buttons.
And here’s a demo of the navigation bar that will open in a new window.


Even without using images the nav bar above has a 3D feel to it and gives the impression that the buttons can being pressed or clicked.
I won’t be going over all the code used to create the navigation bar in this post as I’ve covered most of it before in my simple navigation bar post. What I want to show you today is the part that gives the button the 3D effect, though I’ll provide all the code to create the nav bar at the bottom of this post.
CSS Borders to Give any Element Depth
The trick to the 3D effect, as you can guess from the heading above, is to use css borders to convey a sense of depth from an imaginary light source. There are 3 simple parts to this technique.
- decide where your light source is
- give sides where light shines a border a shade or two lighter than the button color
- give sides that would be in shadows a border a shade or two darker than the button color
Let’s illustrate the three steps above using a grayscale version of our navigation bar to make the color changes easier.


I’ve used #555555 as the color for the grayscale buttons above and we’re assuming our light source is shining from the upper left. That means the top and left sides of the button should appear lighter while the right and bottom sides will be darker.
#555555 is the hexidecimal representation of a medium gray. To make the color darker we want to lower the numbers toward 0 and to make it lighter we want to increase the number toward F. Here’s the border code I used to create the effect.
border-top:2px solid #777777; border-right:2px solid #333333; border-bottom:2px solid #444444; border-left:2px solid #777777;
I’ve used a 2px border for each side and for the top and left sides used a color of #777777 or two shades lighter than the button color #555555. The right side gets a color two shades darker at #333333 and the bottom I only went one shade darker with #444444.
In practice you might only use a 1px border, but I used 2px here to make the effect more obvious. Also I’ll tend to play around a little with the colors until I get something I like, though I usually start by making all the hex values one or two numbers darker or lighter.
With the rollover button the process is similar except that now the top and left sides will be darker and the right and bottom sides will be lighter. Here I used a color of #999999 for the button itself and then for the borders the code is as follows.
border-top:2px solid #777777; border-right:2px solid #aaaaaa; border-bottom:2px solid #aaaaaa; border-left:2px solid #777777;
Again it’s the same as before except for the darker and lighter sides being reversed.
Extending the CSS Border Technique
The technique above is very simple, but there’s no reason you can’t extend it some for more creative possibilities. You can try altering the width of the different borders or play around with the colors to make it look like the light has been cast through a filter. Instead of changing all 6 hex digits you could raise or lower only the red or green values while keeping the blue constant.
One thing I’ll sometimes do is not change the top and bottom border colors on the rollover. That will give the impression that when pressed in the button sits at the same level as the surrounding page, instead of feeling slightly depressed from the page as shown here.
This technique is also hardly limited to navigation buttons. You can use it on any element that accepts a css border. You could for example set up a class for all your buy now buttons using this technique and then apply that class wherever you want a buy now button across your site.
Hopefully in the not too distant future when all browsers can handle things like css gradients and border radius you’ll be able to style the button with code only and eliminate the need to ever use an image for a button. For now you can use either as part of progressive enhancement on your site.
Code Used to Create the Navigation Bar
As promised here’s all the code I used to create the navigation bar at the top of the page. The #nav-wrapper code is there just to have a color that shows what’s going on better than the white of the page. It’s presented here, but not necessary.
The HTML
<div id="nav-wrapper"> <ul id="nav"> <li><a href="">Home</a></li> <li><a href="">About</a></li> <li><a href="">Services</a></li> <li><a href="">FAQ</a></li> <li><a href="">Contact</a></li> </ul> </div>
The CSS
#nav-wrapper { width:465px; margin:0 auto; padding:20px 0; background:#3D3331; } ul#nav { font-family: Verdana; font-size:14px; list-style:none; margin:0 auto; padding:0; width:455px; overflow: auto; } ul#nav li { display:inline; } ul#nav li a { text-decoration:none; display: block; padding:5px 21px; background:#5F3222; color:#eee; float:left; text-align:center; border-top:2px solid #815444; border-right:2px solid #3d1000; border-bottom:2px solid #3d1000; border-left:2px solid #815444; } ul#nav li a:hover { background:#a37666; color:#000; border-top:2px solid #815444; border-right:2px solid #c59888; border-bottom:2px solid #c59888; border-left:2px solid #815444; }
Any tricks you’ve developed to replace images with code?
Subscribe to
TheVanBlog |
Email This Post












The navbar looks nice Steven, I keep mine as simple as I can, too, with CSS.
Quick question though, why is it that when I click the “contact” button in the demo (or hold it down, anyway), a horizontal scrollbar appears below it?
Thanks James.
I’m not sure why you see the horizontal scrollbar, but I’ll guess you’re viewing the demo in some version of IE (if not let me know what browser you are using). It’s probably the width I set on the ul that gets thrown off. It shouldn’t, but that’s my first thought.
I didn’t check the code in IE, but I will as soon as I get a chance. My guess is if you reduced the left and right padding on the links by a px or increase the overall width of the ul by a few px you wouldn’t see the scrollbar.
I’m not seeing the scrollbar on any browser on my end.
I’m using Firefox v3 (I rarely use IE anymore, if ever).
The background color also extends a bit too. Maybe it as something to do with how far I’m ‘zoomed in’. The sizes have always seemed normal to me though, so not sure if that’s it.
That’s possible about being zoomed in. I set the ul to be a specific width so I could center it on the page. The width doesn’t really need to be there though.
If the text size increases then the individual widths of the links will add up to more than the set width on the ul.
I’m not sure why it only happens on the rollover though. And again the width on the ul isn’t necessary.
Odd though since I don’t see the scrollbar in FF even when zooming.
Nothing happened for me on a rollover, the changes only occurred when I physically clicked on the links, or held down the mouse button.
I tried zooming in (making it bigger) and did the same thing, and I got a vertical scrollbar, where the “contacts” link moves right underneath the “home” link.
Weird. The links don’t go anywhere. There all empty hrefs. I wonder if that could be causing the issue. Something to look into I guess.
Hey Steve,
I just wanted to let you know, I found out what was causing the scrollbar to appear, it was the overflow property. No idea why though.
Apparently something was causing the right side of the bar to get bigger as I held down the mouse button on it. (The border perhaps?)
I didn’t see it interfering with anything in my navbar (on a site I’m working on) so I removed it, and everything works and appears fine.
Can’t wait to see wide CSS3 and HTML5 support to create much better navigation buttons. There’s plenty of stuff there that can be used without relying on images.
Hey Yura. How are you. Been awhile since we chatted.
I’m looking forward to css3 and html5 adoption too. Of course that will mean we’ll be waiting on IE and who knows how long that will take.
There’s so much good stuff coming that’s going to open up so many possibilities for designing with code.
Nice trick!
Thanks Jojo
Cool trick Steven
Thanks Soh. About time I returned the favor after all the tricks I’ve picked up from you.
Great navbar, nice and simple! I have one question; is there a way to adjust the width of each tab individually, if you don’t want them all to be the same width?
Thanks,
Keera
Thanks keera.
You actually don’t need to specify the widths like I did here. What I usually do now is give each link some padding and let the size of the tabs grow and contract to match the text.
It’s probably about time I updated this post with a new one.
Well written, but I’m sorry – the navigation bar doesn’t look “Stylish”, it looks 1996.
I think it would be interesting how to make a navigation bar like this with the box-shadow property, without borders.
Ivo
Maybe stylish wasn’t the best choice of words, but I’d hardly say the navigation bar looks like 1996. Do you remember what the web looked like in 1996?
As far as box-shadow is concerned, I’m pretty sure it won’t work yet in IE. Not that you shouldn’t use it, but then you might want a fallback. What’s described here will work cross browser. I’ll save box-shadow for another post, though I’ve seen plenty of posts already covering how to use it.
Thanks,It’s good for my work!
What others are saying about this post
CSS Brigit | How To Create Stylish Navigation Buttons With CSSTwitted by KyleWilliams2
47 CSS Tips & Tricks To Take Your Site To The Next Level | CSS | instantShift
uberVU - social comments
47 consigli e trucchi CSS. #05: Bottoni 3D in CSS | ecoevo Web Design
CSS ile buton yapmak / Fatih Hayrioğlu'nun not defteri